math.nan与'in'运算符结合时的矛盾行为

Jac*_*oge 9 python

我有以下几行代码:

import math as mt

...
...
...

        if mt.isnan (coord0):
            print (111111, coord0, type (coord0), coord0 in (None, mt.nan))
            print (222222, mt.nan, type (mt.nan), mt.nan in (None, mt.nan))
Run Code Online (Sandbox Code Playgroud)

它打印:

111111 nan <class 'float'> False
222222 nan <class 'float'> True
Run Code Online (Sandbox Code Playgroud)

我很困惑......有什么解释吗?

Python 3.6.0,Windows 10

我对Python解释器的质量有着坚定的信心......而且我知道,只要计算机出现错误,实际上我就错了......那么我错过了什么?

[编辑]

(对@COLDSPEED的反应)

确实ID不同:

print (111111, coord0, type (coord0), id (coord0), coord0 in (None, mt.nan))
print (222222, mt.nan, type (mt.nan), id (mt.nan), mt.nan in (None, mt.nan))
Run Code Online (Sandbox Code Playgroud)

打印:

111111 nan <class 'float'> 2149940586968 False
222222 nan <class 'float'> 2151724423496 True
Run Code Online (Sandbox Code Playgroud)

也许有一个很好的理由乳清不是一个真正的单身人士.但我还没有得到它.在我看来,这种行为相当容易出错.

[EDIT2]

(对@Sven Marnach的反应)

仔细阅读@Sven Marnach的答案让我觉得可以理解.这确实是在设计事物时遇到的那种妥协.

冰还很薄:

有了a in (b,)回报True,如果id (a) == id (b)似乎是在与IEEE-754标准,胜算nan应该是不相等nan.

结论必须是虽然a是汇总的,但同时却不是,因为汇总的东西,即b必须被认为不符合aIEEE标准.

想想我isnan将从现在开始使用......

Sve*_*ach 7

您看到的行为是inPython中运算符优化的假象,以及nanIEEE-754标准要求的不等于自身的事实.

inPython中的运算符返回迭代器中的任何元素是否等于您要查找的元素.表达x in it实质上的计算结果为any(x == y for y in it),不同的是一个额外的优化是通过施加CPython的:避免不必调用__eq__每个元素,解释器首先检查是否xy是相同的物体,在这种情况下,它立即返回True.

这种优化几乎适用于所有对象.毕竟,它是每个对象与自身相等的平等基本属性之一.但是,浮点数的IEEE-754标准要求nan != nan,因此NaN打破了这一假设.这将导致你看到奇怪的行为:如果一个人nan恰好是同一对象nan迭代器,在上述优化结果in操作返回True.但是,如果nan迭代器中的对象不是同一个对象,那么Python就会回归__eq__(),而且你得到了False.