Python:max / min内置函数取决于参数顺序

时间:2010-11-21 12:55:18

标签: python math comparison

max(float('nan'), 1)评估为nan

max(1, float('nan'))评估为1

这是预期的行为吗?


感谢您的回答。

当iterable为空时,

max引发异常。当max出现时,为什么Python的nan不会引发异常?或者至少做一些有用的事情,比如返回nan或忽略nan。目前的行为非常不安全,似乎完全不合理。

我发现这种行为更令人惊讶的结果,所以我刚刚发布了related question

3 个答案:

答案 0 :(得分:41)

In [19]: 1>float('nan')
Out[19]: False

In [20]: float('nan')>1
Out[20]: False

float nan既不大于也不小于整数1max从选择第一个元素开始,只有在找到一个严格更大的元素时才替换它。

In [31]: max(1,float('nan'))
Out[31]: 1

由于nan不大于1,因此返回1。

In [32]: max(float('nan'),1)
Out[32]: nan

由于1不大于nan,因此会返回nan


PS。请注意,np.maxfloat('nan')的处理方式不同:

In [36]: import numpy as np
In [91]: np.max([1,float('nan')])
Out[91]: nan

In [92]: np.max([float('nan'),1])
Out[92]: nan

但如果您想忽略np.nan,则可以使用np.nanmax

In [93]: np.nanmax([1,float('nan')])
Out[93]: 1.0

In [94]: np.nanmax([float('nan'),1])
Out[94]: 1.0

答案 1 :(得分:8)

我之前没有见过这个,但这是有道理的。请注意nan是一个非常奇怪的对象:

>>> x = float('nan')
>>> x == x
False
>>> x > 1
False
>>> x < 1
False

我想说max的行为在这种情况下是不确定的 - 你会期待什么答案?唯一合理的行为是假设操作是反对称的。


请注意,您可以通过创建一个损坏的类来重现此行为:

>>> class Broken(object):
...     __le__ = __ge__ = __eq__ = __lt__ = __gt__ = __ne__ =
...     lambda self, other: False
...
>>> x = Broken()
>>> x == x
False
>>> x < 1
False
>>> x > 1
False
>>> max(x, 1)
<__main__.Broken object at 0x024B5B50>
>>> max(1, x)
1

答案 2 :(得分:1)

Max以下列方式工作:

第一项设置为maxval,然后将下一项与此值进行比较。比较将永远返回False:

>>> float('nan') < 1
False
>>> float('nan') > 1
False

因此,如果第一个值是nan,那么(因为比较返回false)它将不会在下一步被替换。

OTOH如果1是第一个,则会发生同样的情况:但在这种情况下,由于设置了1,它将是最大值。

您可以在python代码中验证这一点,只需在Python / bltinmodule.c中查找函数min_max