将 NaN 添加到集合时行为不一致的原因

Causes for inconsistent behavior when adding NaNs to a set

Python 的集合与 NaNs (here live) 的组合有令人费解的(至少对我而言)行为:

>>> float('nan') in {float('nan')}    # example 1
False
>>> nan = float('nan')                # example 2
>>> nan in {nan}
True

起初,我错误地认为这是 == 运算符的行为,但显然不是这种情况,因为这两种情况都会按预期产生 Falsehere live):

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

我主要对这种行为的原因感兴趣。但是,如果有一种方法可以确保一致的行为,那也很高兴知道!

set membership 在考虑相等性检查之前进行身份检查作为短路(CPython 来源在 setobject.c, see also the note below PyObject_RichCompareBool)。

Python 核心开发人员受到这些不变量的激励:

for a in container:
    assert a in container    # this should ALWAYS be true

因此:

assert a in [a]
assert a in (a,)
assert a in {a}

决定确保这些不变量是最重要的优先事项,至于 NaN:哦,好吧。 特殊情况不足以违反规则。有关所有详细信息,请参阅 bpo issue4296

Python assumes identity implies equivalence; contradicts NaN.