虽然numpy.nan
不等于numpy.nan
,(float('nan'), 1)
不等于float('nan', 1)
,
(numpy.nan, 1) == (numpy.nan, 1)
可能是什么原因? Python首先检查id是否相同? 如果在比较元组的项目时首先检查身份,那么为什么不直接比较对象时检查它?
答案 0 :(得分:6)
当你做numpy.nan == numpy.nan
时,确定条件是否为真的是numpy。比较tuples
时,python只是检查元组是否与它们具有相同的对象。您可以numpy
将tuples
转换为numpy
数组,从而让np.array((1, numpy.nan)) == np.array((1,numpy.nan))
>>array([ True, False], dtype=bool)
做出决定。
==
原因是当您使用numpy
个__eq__()
对象时,您正在调用numpy函数nan != nan
,该函数专门针对nan
,因为从数学角度讲nan != nan
是不确定的(可能是任何东西)所以==
是有道理的。但是当你用元组做__eq__()
时,你会调用不关心数学的元组(float('nan'),1)==(float('nan'),1)
函数,只关心python对象是否相同。如果是False
,则会返回float('nan')
,因为float('nan') is float('nan')
的每次调用都会在不同的位置分配内存,因为您可以通过menu.xml
进行检查。
答案 1 :(得分:3)
容器对象可以自由地定义平等对它们意味着什么,对大多数而言,这意味着一件事真的非常重要:
for x in container:
assert x in container
因此,容器通常会在id
检查之前进行__eq__
检查。
答案 2 :(得分:1)
比较元组Python中的两个对象时,首先检查它们是否相同。
请注意numpy.nan is numpy.nan
,但float('nan') is not float('nan')
。
在Objects/tupleobject.c
中,比较的执行方式如下:
for (i = 0; i < vlen && i < wlen; i++) {
int k = PyObject_RichCompareBool(vt->ob_item[i],
wt->ob_item[i], Py_EQ);
if (k < 0)
return NULL;
if (!k)
break;
}
在PyObject_RichCompareBool
中,您可以看到检查是否相等:
if (v == w) {
if (op == Py_EQ)
return 1;
else if (op == Py_NE)
return 0;
}
您可以使用以下示例对此进行验证:
class A(object):
def __eq__(self, other):
print "Checking equality with __eq__"
return True
a1 = A()
a2 = A()
如果您尝试(a1, 1) == (a1, 1)
则不会打印任何内容,而(a1, 1) == (a2, 1)
会使用__eq__
并打印我们的消息。
现在尝试a1 == a1
,看看你是否感到惊讶; P
答案 3 :(得分:0)
如果身份不匹配,元组会首先检查身份然后平等。
(float('nan'),) == (float('nan'),)
是False
只是因为创建了一个不同的对象实例...如果你改为:
x = float('nan')
print (x,) == (x,)
您也会True
,因为x == x
为假,但x is x
为真。
Numpy numpy.nan
是一个静态实例,这就是为什么它不起作用&#34;。
这是一个疯狂的猜测&#34;捷径&#34;首先检查身份是出于性能原因。