在运算符中,float("NaN")和np.nan [英] in operator, float("NaN") and np.nan
问题描述
我曾经相信Python中的in
运算符使用相等性检查==
来检查某些集合中元素的存在,因此element in some_list
大致等同于any(x == element for x in some_list)
.例如:
I used to believe that in
operator in Python checks the presence of element in some collection using equality checking ==
, so element in some_list
is roughly equivalent to any(x == element for x in some_list)
. For example:
True in [1, 2, 3]
# True because True == 1
或
1 in [1., 2., 3.]
# also True because 1 == 1.
但是,众所周知NaN
不等于其自身.所以我希望float("NaN") in [float("NaN")]
是False
.确实是False
.
However, it is well-known that NaN
is not equal to itself. So I expected that float("NaN") in [float("NaN")]
is False
. And it is False
indeed.
但是,如果我们使用numpy.nan
而不是float("NaN")
,情况将大不相同:
However, if we use numpy.nan
instead of float("NaN")
, the situation is quite different:
import numpy as np
np.nan in [np.nan, 1, 2]
# True
但是np.nan == np.nan
仍然给出False
!
怎么可能? np.nan
和float("NaN")
有什么区别? in
如何处理np.nan
?
How is it possible? What's the difference between np.nan
and float("NaN")
? How does in
deal with np.nan
?
推荐答案
要检查该项目是否在列表中,Python首先测试对象身份 ,然后仅在对象存在时测试是否相等是不同的. 1
To check if the item is in the list, Python tests for object identity first, and then tests for equality only if the objects are different.1
float("NaN") in [float("NaN")]
为False,因为比较中涉及到两个不同 NaN
对象.因此,从NaN != NaN
开始,身份测试返回False,然后相等测试也返回False.
float("NaN") in [float("NaN")]
is False because two different NaN
objects are involved in the comparison. The test for identity therefore returns False, and then the test for equality also returns False since NaN != NaN
.
np.nan in [np.nan, 1, 2]
为True,因为比较中涉及到相同 NaN
对象.对象身份测试返回True,因此Python会立即将其识别为列表中的内容.
np.nan in [np.nan, 1, 2]
however is True because the same NaN
object is involved in the comparison. The test for object identity returns True and so Python immediately recognises the item as being in the list.
许多其他Python内置容器类型(例如元组和集合)的__contains__
方法(使用in
调用)是使用相同的检查实现的.
The __contains__
method (invoked using in
) for many of Python's other builtin Container types, such as tuples and sets, is implemented using the same check.
1 至少在CPython中是这样.这里的对象标识意味着可以在相同的内存地址找到对象: PyObject_RichCompareBool
可以在可能进行更复杂的对象比较之前快速比较对象指针.其他Python实现可能会有所不同.
1 At least this is true in CPython. Object identity here means that the objects are found at the same memory address: the contains method for lists is performed using PyObject_RichCompareBool
which quickly compares object pointers before a potentially more complicated object comparison. Other Python implementations may differ.
这篇关于在运算符中,float("NaN")和np.nan的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!