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

时间:2018-07-31 21:05:13

标签: python python-3.x cpython python-internals

NaN s(here live)结合使用时,Python集的行为(至少对我来说是令人困惑的):

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

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

1 个答案:

答案 0 :(得分:5)

set成员资格会在考虑进行相等性检查之前作为短路检查身份(CPython源在setobject.c中,另请参见PyObject_RichCompareBool下面的注释)。

Python核心开发人员受这些不变因素的驱使:

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

Ergo:

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

已决定确保这些不变性是最重要的优先事项,就NaN而言:哦,很好。 特殊情况不足以违反规则。有关所有详细信息,请参见bpo issue4296

Python assumes identity implies equivalence; contradicts NaN