NaNs是字典中的关键 [英] NaNs as key in dictionaries

查看:97
本文介绍了NaNs是字典中的关键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Can anyone explain the following behaviour to me?

>>> import numpy as np
>>> {np.nan: 5}[np.nan]
5
>>> {float64(np.nan): 5}[float64(np.nan)]
KeyError: nan

为什么在第一种情况下有效,但在第二种情况下无效? 此外,我发现以下方法可以工作:

Why does it work in the first case, but not in the second? Additionally, I found that the following DOES work:

>>> a ={a: 5}[a]
float64(np.nan)

推荐答案

这里的问题是NaN不等于自身,这是IEEE标准中对浮点数的定义:

The problem here is that NaN is not equal to itself, as defined in the IEEE standard for floating point numbers:

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

当字典查找键时,它会大致执行以下操作:

When a dictionary looks up a key, it roughly does this:

  1. 计算要查找的键的哈希值.

  1. Compute the hash of the key to be looked up.

对于字典中具有相同哈希值的每个键,请检查其是否与要查找的键匹配.这张支票由

For each key in the dict with the same hash, check if it matches the key to be looked up. This check consists of

a.检查对象身份:如果字典中的键和要查找的键与is运算符指示的对象相同,则找到该键.

a. Checking for object identity: If the key in the dictionary and the key to be looked up are the same object as indicated by the is operator, the key was found.

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

b. If the first check failed, check for equality using the __eq__ operator.

第一个例子成功了,因为np.nannp.nan是同一个对象,所以它们不相等并不重要:

The first example succeeds, since np.nan and np.nan are the same object, so it does not matter they don't compare equal:

>>> numpy.nan is numpy.nan
True

在第二种情况下,np.float64(np.nan)np.float64(np.nan)不是同一对象-这两个构造函数调用创建了两个不同的对象:

In the second case, np.float64(np.nan) and np.float64(np.nan) are not the same object -- the two constructor calls create two distinct objects:

>>> numpy.float64(numpy.nan) is numpy.float64(numpy.nan)
False

由于对象也不相等,因此字典得出未找到键的结论,并抛出KeyError.

Since the objects also do not compare equal, the dictionary concludes the key is not found and throws a KeyError.

您甚至可以执行以下操作:

You can even do this:

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

总而言之,避免使用NaN作为字典键似乎是一个比较明智的主意.

In conclusion, it seems a saner idea to avoid NaN as a dictionary key.

这篇关于NaNs是字典中的关键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆