Python:最大/最小内buildfunction取决于参数顺序
max(float('nan'), 1)
评估为nan
max(1, float('nan'))
计算结果为1
这是预期的行为吗?
感谢您的答案。
当迭代器为空时, max
引发exception。 为什么在nan
存在的时候,Python的max
引发exception呢? 或者至less做一些有用的事情,比如返回nan
或忽略nan
。 目前的行为是非常不安全的,似乎完全不合理。
我发现这种行为更令人惊讶的后果,所以我刚刚发布了一个相关的问题 。
In [19]: 1>float('nan') Out[19]: False In [20]: float('nan')>1 Out[20]: False
float nan
既不大也不小于整数1
。 max
从select第一个元素开始,只有在find一个严格大的元素时才会replace它。
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.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
但是如果你想忽略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
我以前没见过这个,但是有道理。 注意nan
是一个非常奇怪的对象:
>>> x = float('nan') >>> x == x False >>> x > 1 False >>> x < 1 False
我会说,在这种情况下max
的行为是不确定的 – 你会期望什么答案? 唯一明智的行为是假设操作是反对称的。
请注意,您可以通过创build一个破碎的类来重现此行为:
>>> 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
Max的工作方式如下:
第一项被设置为maxval,然后下一个与这个值进行比较。 比较将始终返回False:
>>> float('nan') < 1 False >>> float('nan') > 1 False
所以如果第一个值是nan,那么(因为比较返回false)它不会在下一步被replace。
OTOH如果1是第一个,也会发生同样的情况:但是在这种情况下,因为1被设置,所以是最大的。
你可以在Python代码中validation这个,只要在Python / bltinmodule.c中查找函数min_max