代码之家  ›  专栏  ›  技术社区  ›  max

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

  •  48
  • max  · 技术社区  · 14 年前

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

    max(1, float('nan')) 计算结果为1

    是故意的行为吗?


    谢谢你的回答。

    max 当iterable为空时引发异常。为什么Python的 最大值 在以下情况下引发异常 nan 有人在场吗?或者至少做些有用的事情,比如回报 或者忽略 . 目前的行为非常不安全,似乎完全不合理。

    我发现了一个更令人惊讶的结果,所以我发布了一个 related question .

    3 回复  |  直到 7 年前
        1
  •  42
  •   unutbu    14 年前
    In [19]: 1>float('nan')
    Out[19]: False
    
    In [20]: float('nan')>1
    Out[20]: False
    

    浮子 nan 既不大于也不小于整数 1 . max 从选择第一个元素开始,直到找到严格意义上更大的元素时才替换它。

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

    自从 不大于1,返回1。

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

    因为1不大于 , 被退回。


    注意 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 s,你可以用 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
  •  8
  •   Katriel    14 年前

    我以前没见过,但这是有道理的。请注意 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
    
        3
  •  1
  •   terminus    14 年前

    Max的工作方式如下:

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

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

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

    OTHH如果1是第一次,同样的情况发生:但是在这种情况下,因为1被设置,它将是最大的。

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