什么允许 NaN 与 Python 列表包含运算符一起工作?

问题描述 投票:0回答:1

几乎所有使用 IEEE 浮点值的人都曾遇到过 NaN,或“不是数字”。众所周知,NaN 不等于自身

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

现在,我已经接受了这一点,但有一种奇怪的行为让我难以理解。即,

>>> x in [x]
True

我一直以为

list.__contains__
写的是这样的

def __contains__(self, element):
    for x in self:
        if element == x:
            return True
    return False

即,它在内部对相关数据类型使用了

__eq__
。确实如此。如果我用我自己设计的
__eq__
方法定义自定义类,那么我可以验证 Python 在进行包含检查时确实调用了
__eq__
。但是,怎么可能存在一个值
x
(在我们的例子中是 NaN)使得
x == x
为假但
x in [x]
为真?

我们也可以通过自定义

__eq__
观察到相同的行为。

class Example:

    def __eq__(self, other):
        return False

x = Example()
print(x == x)   # False
print(x in [x]) # True
python nan equality
1个回答
4
投票

According to the docs 它首先使用

is
运算符来检查是否相等,并且由于
x is x
True
x in [x]
也是
True

对于列表、元组、集合、frozenset、字典或collections.deque等容器类型,表达式

x in y
等同于
any(x is e or x == e for e in y)
.

请注意,身份(

is
)不同于平等(
==
)。另请注意,并非所有 NaN 值都由同一个对象表示,因此如果您尝试使用两个不同的 NaN 对象进行测试:

>>> float('nan') in [float('nan')]
False

你会看到不同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.