Python:可用的最大值和最小值

时间:2012-05-14 01:16:08

标签: python python-3.x

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 has removed sys.maxint关于所有内容促进多头和限制不再适用的理论。

PEP 326,顶部和底部值的一个案例,在Python中提高了参考最小值和最大值。新的排序行为documented

由于PEP 326被拒绝,在Python 2X和Python 3000上使用整数和浮点数和长整数的最小值和最大值有用,可用的定义是什么?

修改

有几个答案是“只使用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('inf'),需要将long值转换为float,转换将导致OverflowError ...

结论

感谢大家的回答和评论。我选择了TryPyPy的answer,因为它似乎最符合我的要求:维基百科entry on infinity.

中描述的绝对最大和绝对最小值

通过这个问题,我了解到long或int值没有转换为float,以便完成float('inf') > 2**5000的比较。我不知道。

3 个答案:

答案 0 :(得分:14)

对于数值比较,+- float("inf")应该有效。

编辑:它并不总是有效(但涵盖现实案例):

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

当然,需要付出更多努力才能涵盖'或相同'的变体。并且它无法解决无法对包含Noneint s的列表进行排序的一般问题,但这也应该可以通过一点包装和/或装饰 - 排序 - 未装饰的魔法来实现(例如,排序(typename, value))的元组列表。

答案 1 :(得分:10)

您的问题中已经有了最明显的选择:float('-inf')float('inf')

另外,请注意None小于所有内容且空元组高于所有内容,但在Py2中没有保证,例如,Jython和PyPy完全有权使用如果他们愿意,可以使用不同的顺序。所有保证的是一个正在运行的解释器副本内的一致性 - 实际的顺序是任意的。

答案 2 :(得分:3)

在cPython中,cmp不会隐式执行转换。即,这有效:

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