是什么允许 NaN 使用 Python 列表包含运算符?

What allows NaN to work with the Python list inclusion operator?

提问人:Silvio Mayolo 提问时间:4/20/2023 更新时间:4/20/2023 访问量:51

问:

几乎任何使用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

即,它在内部用于相关数据类型。确实如此。如果我使用自己设计的方法定义一个自定义类,那么我可以验证 Python 在执行包含检查时是否确实调用了。但是,怎么可能存在一个值(在我们的例子中为 NaN),这样它是假的,但却是真的呢?__eq____eq____eq__xx == xx in [x]

我们也可以通过自定义来观察相同的行为。__eq__

class Example:

    def __eq__(self, other):
        return False

x = Example()
print(x == x)   # False
print(x in [x]) # True
蟒蛇 平等

评论


答:

5赞 Selcuk 4/20/2023 #1

根据文档,它首先使用运算符来检查是否相等,并且由于是,因此也是:isx is xTruex in [x]True

对于容器类型(如 list、tuple、set、frozenset、dict 或 collections.deque),表达式等效于 .x in yany(x is e or x == e for e in y)

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

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

你会看到不同的结果。