python - 在运算符中, float ("NaN")和 np.nan

标签 python numpy containers nan

我曾经相信 Python 中的 in 运算符使用相等性检查 == 来检查某个集合中元素的存在,所以 element in some_list 大致相当于 any(x == element for x in some_list)。例如:

True in [1, 2, 3]
# True because True == 1

1 in [1., 2., 3.]
# also True because 1 == 1.

然而,众所周知 NaN 不等于自身。所以我预计 [float("NaN")] 中的 float("NaN") 是 False。确实是False

但是,如果我们使用 numpy.nan 而不是 float("NaN"),情况就大不相同了:

import numpy as np
np.nan in [np.nan, 1, 2]
# True

但是 np.nan == np.nan 仍然给出 False!

这怎么可能? np.nanfloat("NaN") 有什么区别? in 如何处理np.nan

最佳答案

为了检查项目是否在列表中,Python 测试对象身份首先,然后仅在对象不同时测试是否相等。1

[float("NaN")]
中的

float("NaN") 为 False,因为在比较。因此,身份测试返回 False,然后相等性测试也返回 False,因为 NaN != NaN

np.nan in [np.nan, 1, 2] 然而是 True 因为 same NaN 对象参与比较.对象身份的测试返回 True,因此 Python 立即将项目识别为在列表中。

Python 的许多其他内置容器类型(例如元组和集合)的 __contains__ 方法(使用 in 调用)使用相同的检查来实现。


1 至少在 CPython 中是这样。这里的对象标识意味着对象位于相同的内存地址:contains method for lists。使用 PyObject_RichCompareBool 执行在可能更复杂的对象比较之前快速比较对象指针。其他 Python 实现可能会有所不同。

关于python - 在运算符中, float ("NaN")和 np.nan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47721635/

相关文章:

python - 仅使用圆形网格绘制三角形,python

python slice 方法并不总是返回内存中的新地址?

python - Pandas 测试一列是否是另一列的子集? (即 B 列包含 A 列)

python - Numpy reshape 行为异常

python - 使用 Cython 定义自定义 pandas 聚合函数

python - `self[key] += value` 的魔术方法?

python - 订购 list

python - Pandas 四舍五入小数不起作用

C++:访问 shared_ptr 的容器应该返回原始还是共享 ptr?

java - <Key, <pair Of Type1,pair Of Type2>> 的最佳容器