python - NaN 作为字典中的关键

标签 python numpy nan

任何人都可以向我解释以下行为吗?

>>> 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 标准中所定义的那样:

>>> float("nan") == float("nan")
False

当字典查找一个键时,它大致是这样做的:

  1. 计算要查找的 key 的哈希值。

  2. 对于字典中具有相同哈希值的每个键,检查它是否与要查找的键匹配。此检查包括

    一个。检查对象身份:如果字典中的键和要查找的键是同一对象,如 is 运算符所示,则找到了键。

    如果第一次检查失败,请使用 __eq__ 运算符检查是否相等。

第一个例子成功了,因为 np.nannp.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

由于对象也不相等,字典断定找不到键并抛出 KeyError

你甚至可以这样做:

>>> a = float("nan")
>>> b = float("nan")
>>> {a: 1, b: 2}
{nan: 1, nan: 2}

总而言之,避免将 NaN 作为字典键似乎是一个更明智的想法。

关于python - NaN 作为字典中的关键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49724089/

相关文章:

python 非常缓慢地释放输出到 tee

python - 这在 random.shuffle 的文档中意味着什么?

python - 使用 numpy 的 python 中的多线性映射

java - float 或 double 的 NaN 和 Infinity 如何存储在内存中?

python - Pandas DataFrame 的条件均值

c++ - 在 C++ 中检查 double (或 float )是否为 NaN

python - pypyodbc 在 isql 连接时不连接?

python - 如何使用Python可靠地提取URL中包含的URL?

python - 将 numpy 数组列表保存到磁盘上

python - 乘以 numpy 中包含图像的张量