令我自己非常沮丧的是,我设法在python中列出了一个对象列表,导致以下操作失败:
if foo in lst:
lst.index(foo) # ValueError: <foo> is not in list
我向你保证,这里没有欺骗:
foo
是一个具有自定义__hash__
和__eq__
的对象,不会在其他地方进行修改- 这两个函数都是幂等的并且不修改状态
lst
是一个没有诅咒的标准python[]
obj in listobject
(或listobject.__contains__(obj)
)和listobject.index()
之间的唯一区别是比较是反转。
list_contains
会:
for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
Py_EQ);
而CCD_ 10是;
for (i = start; i < stop && i < Py_SIZE(self); i++) {
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
其中el
和v
是所查找的对象,而PyList_GET_ITEM(a, i)
和self->ob_item[i]
是列表中包含的对象。
因此lst.index()
抛出一个ValueError
异常,因为所有的other.__eq__(foo)
调用都返回False
,而foo.__eq__(other)
从未被查询过。CCD_ 20工作是因为CCD_ 21确实返回至少一个值的CCD_。
您还没有给我们一个示例列表和__eq__
实现来验证为什么__eq__
为所有other.__eq__(foo)
调用返回False
。