在python列表中,“in”的行为与“index”的行为有何不同



令我自己非常沮丧的是,我设法在python中列出了一个对象列表,导致以下操作失败:

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

我向你保证,这里没有欺骗:

  1. foo是一个具有自定义__hash____eq__的对象,不会在其他地方进行修改
  2. 这两个函数都是幂等的并且不修改状态
  3. 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);

其中elv是所查找的对象,而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

最新更新