2012-05-14 5 views
21

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

Полезный ярлык (в 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 has removedsys.maxint на теории, что все Интс не способствуют долгот и предел больше не применяется.

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

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

Редактировать

Несколько ответов по линии «просто использовать MAXV = поплавок („инф“)» ... Поэтому я имею в виду, однако удаленный возможность, это:

>>> 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 

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

Заключения

Спасибо всем для ваших ответов и комментариев. Я выбрал TryPyPy-х answer, потому что это казалось наиболее рядный с тем, что я спрашивал: абсолютное наибольшее и абсолютное наименьшее значение, как описано в Википедии entry on infinity.

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

+2

Что случилось с 'поплавка («инф»)' или, если вам нужен номер, 'sys.float_info.max'? –

+1

IITR hetrogeneous values, где упорядочено по алфавиту по названию их типа - вряд ли когда-либо полезно –

+3

«Python3000 удалил sys.maxint по теории, что все ints продвигаются к longs, и лимит больше не применяется». Нет, Python3000 удалил 'int '* период *. Все целые числа теперь 'long', поэтому он был переименован. –

ответ

10

Для численных сравнений +- 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 s и int s, но это тоже должно быть возможно с помощью небольшой маскировки обертывания и/или украшения-сортировки-undecorate (например, сортировка списка кортежей (typename, value)).

+1

FWIW, этот мошеннический перерыв, когда у вас внезапно появилось много МИН (или эквивалентных читеров) в контейнере, что еще хуже, если это автосортировка. – TryPyPy

9

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

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

+0

Вы даже можете назначить поплавковые формы бесконечности 'MAX' и' MIN' и быть на вашем пути. – mgold

+4

'3 >> поплавок ('- инф') <(3 + 4к)' ' Traceback (самый последний вызов последнего):' ' Файл "", строка 1, в ' ' TypeError: unorderable типы: float()

+1

@ IgnacioVazquez-Abrams: не очень справедливо, так как любой список, содержащий комплексные числа, также является несортируемым (и любая пара комплексов, если на то пошло) :) – TryPyPy

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... 

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

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

'>>> cmp (1.0 ** 4999,10.0 ** 5000)' –

+3

OK - '>>>()> 10.0 ** 5000' производит переполнение слишком ... –

+2

и' cmp() 'ушло в Py3 тоже. –

Смежные вопросы