Python: используемые значения Max и Min - программирование
Подтвердить что ты не робот

Python: используемые значения Max и Min

Python 2.x позволяет сравнивать гетерогенные типы.

Полезный ярлык (в Python 2.7 здесь) заключается в том, что None сравнивается меньше любого целого или плавающего значения:

>>> None < float('-inf') < -sys.maxint * 2l < -sys.maxint
True

И в Python 2.7 пустой кортеж () является бесконечным значением:

>>> () > float('inf') > sys.maxint
True

Этот ярлык полезен, когда можно сортировать смешанный список int и float и вы хотите иметь абсолютный минимум и максимум для ссылки.

Этот ярлык был удален в Python 3000 (это Python 3.2):

>>> None < 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()

Кроме того, Python3000 удалил sys.maxint по теории, что все ints продвигаются к длинным, и лимит больше не применяется.

PEP 326, пример для верхних и нижних значений, вывел ссылку min и max в Python. Новое упорядоченное поведение задокументировано.

Поскольку PEP 326 был отклонен, какие полезные, пригодные для использования определения для значения min и max, которые работают с целыми числами и плаваниями и longs на Python 2X и Python 3000?

Edit

Несколько ответов идут по строкам "просто используйте maxv = float (" inf ")"... Причина, по которой я думаю, насколько это возможно, заключается в следующем:

>>> float(2**5000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float 

и

>>> cmp(1.0**4999,10.0**5000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')

Тем не менее:

>>> () > 2**5000
True

Для того чтобы cmp до значения float, float('inf'), длинное значение нужно было бы преобразовать в float, и преобразование вызовет OverflowError...

Заключение

Спасибо всем за ваши ответы и комментарии. Я выбрал TryPyPy ответ, потому что он казался наиболее встроенным в то, что я спрашивал: абсолютное наибольшее и абсолютное наименьшее значение, как описано в Wikipedia запись на бесконечность.

С этим вопросом я узнал, что значение long или int не преобразуется в float, чтобы завершить сравнение float('inf') > 2**5000. Я этого не знал.

4b9b3361

Ответ 1

Для численных сравнений +- float("inf") должен работать.

EDIT: он не всегда работает (но охватывает реалистичные случаи):

print(list(sorted([float("nan"), float("inf"), float("-inf"), float("nan"), float("nan")])))
# NaNs sort above and below +-Inf
# However, sorting a container with NaNs makes little sense, so not a real issue.

Чтобы иметь объекты, которые сравниваются как выше или ниже с любыми другими произвольными объектами (в том числе inf, но исключая другие читеры, как показано ниже), вы можете создавать классы, которые определяют свои максимальные/минимальные значения в своих специальных методах для сравнения:

class _max:
    def __lt__(self, other): return False
    def __gt__(self, other): return True

class _min:
    def __lt__(self, other): return True
    def __gt__(self, other): return False

MAX, MIN = _max(), _min()

print(list(sorted([float("nan"), MAX, float('inf'), MIN, float('-inf'), 0,float("nan")])))
# [<__main__._min object at 0xb756298c>, nan, -inf, 0, inf, nan, <__main__._max object at 0xb756296c>]

Конечно, для покрытия вариантов "или равно" требуется больше усилий. И это не решит общую проблему неспособности сортировать список, содержащий None и int s, но это тоже должно быть возможно с помощью небольшой маскировки обертывания и/или украшения-сортировки-undecorate (например, сортировка списка кортежей (typename, value)).

Ответ 2

У вас есть наиболее очевидный выбор в вашем вопросе: float('-inf') и float('inf').

Кроме того, обратите внимание, что None меньше, чем все, и пустой кортеж, который выше, чем все, никогда не гарантировался в Py2, и, например, Jython и PyPy имеют полное право использовать другой порядок, если им это нравится, Все, что гарантировано, является согласованностью в пределах одной запущенной копии интерпретатора - фактический порядок произволен.

Ответ 3

В cPython cmp не выполняет преобразование в float неявно. т.е. это работает:

>>> float('inf') > 2**5000
True

Хотя это явно выполняет преобразование страха:

>>> float('inf') > float(2**5000)
Overflow...

Правильный ответ, ИМХО, не является само по себе изменением логики:

def func_with_min():
   minval=None
   for loop in list_with_mins:
      if minval is None or minval<minseen:
          # do that min thing you wanna do...

Если вы хотите иметь значение, то float('-inf') для min и float('inf') довольно безопасно. Однако не забудьте кэшировать это вне цикла:

def func():
   minval=float('-inf')
   for loop in now_you_can_loop:
       # otherwise float('-inf') is kinda slow