31

Python 2.x 允许比较异构类型。

一个有用的快捷方式(此处为 Python 2.7)是None比较小于任何整数或浮点值:

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

在 Python 2.7 中,一个空元组()是一个无限值:

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

当您可能对整数和浮点数的混合列表进行排序并希望有一个绝对最小值和最大值可供参考时,此快捷方式很有用。

但是,此快捷方式已在 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了所有 int 都提升为 long 并且限制不再适用的理论。

PEP 326 , A Case for Top and Bottom Values, 在 Python 中提高了参考最小值和最大值。记录了新的排序行为。

由于 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 值转换为浮点数,并且转换会导致OverflowError...

结论

谢谢大家的回答和评论。我选择了 TryPyPy 的答案,因为它似乎最符合我的要求:绝对最大和绝对最小值,如 Wikipedia entry on infinity 中所述。

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

4

3 回答 3

16

对于数值比较,+- 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>]

当然,覆盖“或等于”变体需要更多的努力。并且它不会解决无法对包含Nones 和ints 的列表进行排序的一般问题,但是通过一点包装和/或 decorate-sort-undecorate 魔法(例如,对 的元组列表进行排序(typename, value))也应该可以解决这个问题。

于 2012-05-14T03:52:35.700 回答
11

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

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

于 2012-05-14T01:26:14.550 回答
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')for min 并且float('inf')非常安全。但是,请务必将其缓存在循环之外:

def func():
   minval=float('-inf')
   for loop in now_you_can_loop:
       # otherwise float('-inf') is kinda slow
于 2012-05-14T04:43:52.550 回答