difference between `x in list` and `list.index(x)` for instances of a new-style class

bpgbaires at gmail.com bpgbaires at gmail.com
Sat Dec 29 09:49:42 EST 2007


On 28 dic, 20:12, Riccardo Murri <riccardo.mu... at gmail.com> wrote:

> The list `self.base` contains "canonical" forms of the graphs and the
> `graph` object must compare equal to some item of the list, which
> indeed it does::
>
>   (Pydb) p graph == self.base[27]  
>   True
>
>   (Pydb) p graph in self.base
>   True
>
> However, I cannot directly get the index of the canonical graph (the
> number "27" above was found by manual inspection)::
>
>   (Pydb) self.base.index(graph)
>   *** ValueError: list.index(x): x not in list
>
> All graphs are instances of a `Graph` new-style class that implements
> comparison operators `__eq__` and `__ne__`, but no other rich-compare
> stuff.
>
> I'm using Python 2.5::
>
>   Python 2.5 (release25-maint, Dec  9 2006, 16:17:58)
>   [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-20)] on linux2
>
> So my question is: what are the implementation differences between `x
> in list` and `list.index(x)` and why can one report that an item is in
> the list while the other cannot find its index?  Should I add
> something to the `Graph` class so that `index` works?

(I've checked on 2.5.1 but I don't see any relevant differences with
the 2.5 version). Looking at the source for both methods, they only
use the __eq__ operator, but there is a slight difference: while one
evaluates list[i]==x, the other reverses the operands. If your __eq__
is not reflexive, that could explain the difference.

class Graph(object):
  def __init__(self, *items):
    self.items = items

  def __eq__(self, other):
    if len(self.items)>len(other.items): return False
    return self.items == other.items[:len(self.items)]

py> List = [Graph(1,2,3), Graph(4,5,6), Graph(1,2,3,4)]
py> g = Graph(1,2)
py> g in List
True
py> List.index(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.index(x): x not in list
py> List[0]==g
False
py> g==List[0]
True

In your example, see if self.base[27]==graph is still True.

--
Gabriel Genellina



More information about the Python-list mailing list