NaNs是字典中的关键
谁能向我解释以下行为?
>>> import numpy as np
>>> {np.nan: 5}[np.nan]
5
>>> {float64(np.nan): 5}[float64(np.nan)]
KeyError: nan
为什么在第一种情况下有效,但在第二种情况下无效?此外,我发现以下方法可以工作:
>>> a ={a: 5}[a]
float64(np.nan)
-
这里的问题是,NaN不等于其自身,如IEEE标准中对浮点数的定义:
>>> float("nan") == float("nan") False
当字典查找键时,它大致执行以下操作:
-
计算要查找的键的哈希值。
-
对于字典中具有相同哈希值的每个键,请检查其是否与要查找的键匹配。此检查包括
一种。检查对象身份:如果字典中的键和要查找
is
的键与操作员指示的对象相同,则找到该键。b。如果第一次检查失败,请使用
__eq__
运算符检查是否相等。第一个例子成功了,因为
np.nan
和np.nan
是相同的对象,所以不要将它们不相等都没关系:>>> numpy.nan is numpy.nan True
在第二种情况下,
np.float64(np.nan)
并且np.float64(np.nan)
它们不是同一对象—两个构造函数调用创建两个不同的对象:>>> numpy.float64(numpy.nan) is numpy.float64(numpy.nan) False
由于对象也不相等,因此字典得出未找到键的结论,并抛出a
KeyError
。您甚至可以这样做:
>>> a = float("nan") >>> b = float("nan") >>> {a: 1, b: 2} {nan: 1, nan: 2}
总之,避免使用NaN作为字典键似乎是一个比较明智的主意。
-