gpt4 book ai didi

python - Python 2.7 如何比较列表中的项目

转载 作者:太空狗 更新时间:2023-10-29 21:13:00 25 4
gpt4 key购买 nike

我今天遇到了这个有趣的例子

class TestableEq(object):
def __init__(self):
self.eq_run = False
def __eq__(self, other):
self.eq_run = True
if isinstance(other, TestableEq):
other.eq_run = True
return self is other

>>> eq = TestableEq()
>>> eq.eq_run
False
>>> eq == eq
True
>>> eq.eq_run
True
>>> eq = TestableEq()
>>> eq is eq
True
>>> eq.eq_run
False
>>> [eq] == [eq]
True
>>> eq.eq_run # Should be True, right?
False
>>> (eq,) == (eq,) # Maybe with tuples?
True
>>> eq.eq_run
False
>>> {'eq': eq} == {'eq': eq} # dicts?
True
>>> eq.eq_run
False
>>> import numpy as np # Surely NumPy works as expected
>>> np.array([eq]) == np.array([eq])
True
>>> eq.eq_run
False

因此,容器内的比较在 Python 中的工作方式似乎有所不同。我希望对 == 的调用将使用每个对象的 __eq__ 实现,否则有什么意义呢?另外

class TestableEq2(object):
def __init__(self):
self.eq_run = False
def __eq__(self, other):
self.eq_run = True
other.eq_run = True
return False

>>> eq = TestableEq2()
>>> [eq] == [eq]
True
>>> eq.eq_run
False
>>> eq == eq
False
>>> eq.eq_run
True

这是否意味着 Python 在容器的 __eq__ 实现中使用 is 来代替?有解决办法吗?

我的用例是我正在构建一个继承自某些 collection ABC 的数据结构,我想编写测试以确保我的结构运行正确。我认为注入(inject)比较时记录的值会很简单,但令我惊讶的是,在检查以确保比较发生时测试失败了。

编辑:我应该提到这是在 Python 2.7 上,但我在 3.3 上看到了相同的行为。

最佳答案

如果项目相同(),CPython 的底层实现将跳过列表中项目的相等性检查(==)。

CPython 将其用作假设身份意味着相等的优化。

这记录在 PyObject_RichCompareBool 中,用于比较项目:

Note: If o1 and o2 are the same object, PyObject_RichCompareBool() will always return 1 for Py_EQ and 0 for Py_NE.

来自listobject.c实现:

/* Search for the first index where items are different */
for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
int k = PyObject_RichCompareBool(vl->ob_item[i],
wl->ob_item[i], Py_EQ);
// k is 1 if objects are the same
// because of RichCmopareBool's behaviour
if (k < 0)
return NULL;
if (!k)
break;
}

如您所见,只要 RichCompareBool1 (True),项目就不会被检查。

来自object.c PyObject_RichCompareBool 的实现:

/* Quick result when objects are the same.
Guarantees that identity implies equality. */
if (v == w) {
if (op == Py_EQ)
return 1;
else if (op == Py_NE)
return 0;
}
// ... actually deep-compare objects

要覆盖它,您必须手动比较项目。

关于python - Python 2.7 如何比较列表中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29215418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com