0

令我沮丧的是,我设法在 python 中创建了一个对象列表,使得以下失败:

if foo in lst:
    lst.index(foo) # ValueError: <foo> is not in list

我向你保证,这里没有诡计:

  1. foo是一个带有自定义__hash__and的对象__eq__,并且没有在其他地方被修改
  2. 两个函数都是幂等的,不修改状态
  3. lst[]是一个没有诅咒的标准蟒蛇
4

1 回答 1

4

obj in listobject(or 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);

虽然listindex有;

for (i = start; i < stop && i < Py_SIZE(self); i++) {
    int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);

其中elv是查找的对象, 和PyList_GET_ITEM(a, i)self->ob_item[i]列表中包含的对象。

所以lst.index()抛出一个ValueError异常,因为所有的other.__eq__(foo)调用都返回False并且foo.__eq__(other)从未被咨询过。foo in lst有效,因为foo.__eq__(other)确实返回True至少一个值。

您还没有给我们一个示例列表和__eq__实现来验证为什么 所有调用都__eq__返回。Falseother.__eq__(foo)

于 2014-04-22T17:58:11.543 回答