我曾经相信 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.nan
和 float("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/