Python: max/min builtin functions depend on parameter order

非 Y 不嫁゛ 提交于 2019-12-17 16:24:54

问题


max(float('nan'), 1) evaluates to nan

max(1, float('nan')) evaluates to 1

Is it the intended behavior?


Thanks for the answers.

max raises an exception when the iterable is empty. Why wouldn't Python's max raise an exception when nan is present? Or at least do something useful, like return nan or ignore nan. The current behavior is very unsafe and seems completely unreasonable.

I found an even more surprising consequence of this behavior, so I just posted a related question.


回答1:


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

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

The float nan is neither bigger nor smaller than the integer 1. max starts by choosing the first element, and only replaces it when it finds an element which is strictly larger.

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

Since nan is not larger than 1, 1 is returned.

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

Since 1 is not larger than nan, nan is returned.


PS. Note that np.max treats float('nan') differently:

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

but if you wish to ignore np.nans, you can use np.nanmax:

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

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



回答2:


I haven't seen this before, but it makes sense. Notice that nan is a very weird object:

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

I would say that the behaviour of max is undefined in this case -- what answer would you expect? The only sensible behaviour is to assume that the operations are antisymmetric.


Notice that you can reproduce this behaviour by making a broken class:

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



回答3:


Max works the following way:

The first item is set as maxval and then the next is compared to this value. The comparation will always return False:

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

So if the first value is nan, then (since the comparation returns false) it will not be replaced upon the next step.

OTOH if 1 is the first, the same happens: but in this case, since 1 was set, it will be the maximum.

You can verify this in the python code, just look up the function min_max in Python/bltinmodule.c



来源:https://stackoverflow.com/questions/4237914/python-max-min-builtin-functions-depend-on-parameter-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!