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

max*_*max 50 python math comparison

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

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

这是预期的行为吗?


谢谢你的回答.

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

我发现这种行为更令人惊讶的结果,所以我刚发布了一个相关的问题.

unu*_*tbu 42

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

In [20]: float('nan')>1
Out[20]: False
Run Code Online (Sandbox Code Playgroud)

浮点nan既不大也不小于整数1. max首先选择第一个元素,只有当它找到一个严格更大的元素时才替换它.

In [31]: max(1,float('nan'))
Out[31]: 1
Run Code Online (Sandbox Code Playgroud)

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

In [32]: max(float('nan'),1)
Out[32]: nan
Run Code Online (Sandbox Code Playgroud)

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


PS.请注意,np.max对待方式float('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
Run Code Online (Sandbox Code Playgroud)

但是如果你想忽略np.nans,你可以使用np.nanmax:

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

In [94]: np.nanmax([float('nan'),1])
Out[94]: 1.0
Run Code Online (Sandbox Code Playgroud)

  • @javadba 关于 NaN 的 IEEE-754 规则之一是“当其中一个或两个操作数为 NaN 时,比较 EQ、GT、GE、LT 和 LE,则返回 FALSE”。所以它的字面意思是“所有实现浮点数的编程语言”,而不是“只有 python ..”。 (2认同)

Kat*_*iel 8

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

>>> x = float('nan')
>>> x == x
False
>>> x > 1
False
>>> x < 1
False
Run Code Online (Sandbox Code Playgroud)

我会说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
Run Code Online (Sandbox Code Playgroud)