为什么(numpy.nan,1)==(numpy.nan,1)?

时间:2015-06-03 08:40:29

标签: python

虽然numpy.nan不等于numpy.nan(float('nan'), 1)不等于float('nan', 1)

(numpy.nan, 1) == (numpy.nan, 1)

可能是什么原因? Python首先检查id是否相同? 如果在比较元组的项目时首先检查身份,那么为什么不直接比较对象时检查它?

4 个答案:

答案 0 :(得分:6)

当你做numpy.nan == numpy.nan时,确定条件是否为真的是numpy。比较tuples时,python只是检查元组是否与它们具有相同的对象。您可以numpytuples转换为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;首先检查身份是出于性能原因。