Как зажимать целое число до некоторого диапазона? (в Python)

У меня есть следующий код:

new_index = index + offset if new_index < 0: new_index = 0 if new_index >= len(mylist): new_index = len(mylist) - 1 return mylist[new_index] 

В принципе, я вычисляю новый индекс и использую его, чтобы найти какой-то элемент из списка. Чтобы убедиться, что индекс находится внутри границ списка, мне нужно было написать те выражения 2 if распределены в 4 строки. Это довольно многословие, немного уродливое … Разве я говорю, что он совершенно непитонический .

Есть ли еще более простое и компактное решение? (и больше питонов )

Да, я знаю, что могу использовать, if else в одной строке, но не читаем:

 new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index 

Я также знаю, что могу объединить max() и min() вместе. Это более компактно, но я чувствую, что это немного неясное, сложнее найти ошибки, если я наберу это неправильно. Другими словами, я не считаю это очень простым.

 new_index = max(0, min(new_index, len(mylist)-1)) 

  • Обработка \ r \ n vs \ n новых строк в python на Mac и Windows
  • Python, если со многими или в контрактной форме
  • Python: deepcopy (list) vs new_list = old_list
  • Как установить предопределенное значение формы из ссылки в Django?
  • Использовать Django ORM как автономный
  • соединяют несколько подпроцессов
  • 9 Solutions collect form web for “Как зажимать целое число до некоторого диапазона? (в Python)”

    На самом деле это довольно ясно. Многие люди учатся быстро. Вы можете использовать комментарий, чтобы помочь им.

     new_index = max(0, min(new_index, len(mylist)-1)) 
     sorted((minval, value, maxval))[1] 

    например:

     >>> minval=3 >>> maxval=7 >>> for value in range(10): ... print sorted((minval, value, maxval))[1] ... 3 3 3 3 4 5 6 7 7 7 

    См. Numpy.clip :

     index = numpy.clip(index, 0, len(my_list) - 1) 

    много интересных ответов здесь, все о том же, кроме … что быстрее?

     import numpy np_clip = numpy.clip mm_clip = lambda x, l, u: max(l, min(u, x)) s_clip = lambda x, l, u: sorted((x, l, u))[1] py_clip = lambda x, l, u: l if x < l else u if x > u else x 
     >>> import random >>> rrange = random.randrange >>> %timeit mm_clip(rrange(100), 10, 90) 1000000 loops, best of 3: 1.02 µs per loop >>> %timeit s_clip(rrange(100), 10, 90) 1000000 loops, best of 3: 1.21 µs per loop >>> %timeit np_clip(rrange(100), 10, 90) 100000 loops, best of 3: 6.12 µs per loop >>> %timeit py_clip(rrange(100), 10, 90) 1000000 loops, best of 3: 783 ns per loop 

    paxdiablo имеет это !, используйте простой ol 'python. Версия numpy, возможно, не удивительно, самая медленная партия. Вероятно, потому что он ищет массивы, где другие версии просто заказывают свои аргументы.

    Связывание max() и min() вместе – это нормальная идиома, которую я видел. Если вам трудно читать, напишите вспомогательную функцию для инкапсуляции операции:

     def clamp(minimum, x, maximum): return max(minimum, min(x, maximum)) 

    Что случилось с моим любимым читаемым языком Python? 🙂

    Серьезно, просто сделайте это функцией:

     def addInRange (val, add, minval, maxval): newval = val + add if newval < minval: return minval if newval > maxval: return maxval return newval 

    то просто назовите его чем-то вроде:

     val = addInRange (val, 7, 0, 42) 

    Или простое, более гибкое решение, в котором вы сами делаете расчет:

     def restrict (val, minval, maxval): if val < minval: return minval if val > maxval: return maxval return val x = restrict (x+10, 0, 42) 

    Если бы вы этого захотели, вы даже могли бы составить список min / max, чтобы он выглядел более «математически чистым»:

     x = restrict (val+7, [0, 42]) 

    Если ваш код кажется слишком громоздким, функция может помочь:

     def clamp(minvalue, value, maxvalue): return max(minvalue, min(value, maxvalue)) new_index = clamp(0, new_index, len(mylist)-1) 

    Избегайте писать функции для таких небольших задач, если вы их не применяете часто, так как это загромождает ваш код.

    для отдельных значений:

     min(clamp_max, max(clamp_min, value)) 

    для списков значений:

     map(lambda x: min(clamp_max, max(clamp_min, x)), values) 

    Мне это кажется более пифоническим:

     >>> def clip(val, min_, max_): ... return min_ if val < min_ else max_ if val > max_ else val 

    Несколько тестов:

     >>> clip(5, 2, 7) 5 >>> clip(1, 2, 7) 2 >>> clip(8, 2, 7) 7 
    Python - лучший язык программирования в мире.