Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > difference between `x in list` and `list.index(x)` for instances of anew-style class

Reply
Thread Tools

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

 
 
Riccardo Murri
Guest
Posts: n/a
 
      12-28-2007

Hello,

I have some code that stops when trying to find a graph in a list of
similar graphs::

(Pydb) list
110 try:
111 canonical = self.base[self.base.index(graph)]
112 except ValueError:
113 raise ValueError, \
114 "Cannot find canonical representative for graph `%s`." \
115 -> % (repr(graph),)
116
....

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:5
[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?

Thanks for any hint!


--
Riccardo Murri, via Galeazzo Alessi 61, 00176 Roma

 
Reply With Quote
 
 
 
 
bpgbaires@gmail.com
Guest
Posts: n/a
 
      12-29-2007
On 28 dic, 20:12, Riccardo Murri <(E-Mail Removed)> 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:5
> * [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
 
Reply With Quote
 
 
 
 
Riccardo Murri
Guest
Posts: n/a
 
      12-30-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> On 28 dic, 20:12, Riccardo Murri <(E-Mail Removed)> 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:5
>> * [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.
>


That was indeed the reason: a bug in Graph.__eq__ broke reflexivity in
certain cases.

Thank you very much!!

--
Riccardo Murri, via Galeazzo Alessi 61, 00176 Roma

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      12-30-2007
On 30 dic, 06:24, Riccardo Murri <(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
>
> >> * (Pydb) p graph == self.base[27] *
> >> * True
> >> * (Pydb) p graph in self.base
> >> * True
> >> * (Pydb) self.base.index(graph)
> >> * *** ValueError: list.index(x): x not in list


> > 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.

>
> That was indeed the reason: a bug in Graph.__eq__ broke reflexivity in
> certain cases.


Combined with some other WTF bugs I've found at work, lately I feel
more like a detective than a software developer

--
Gabriel Genellina
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dicts,instances,containers, slotted instances, et cetera. ocschwar@gmail.com Python 8 01-29-2009 09:52 AM
what is the difference between abstract class and pure abstract class? skishorev@yahoo.co.in C++ 4 05-17-2006 08:07 AM
share function argument between subsequent calls but not between class instances! K. Jansma Python 7 02-21-2006 01:31 PM
Difference between bin and obj directories and difference between project references and dll references jakk ASP .Net 4 03-22-2005 09:23 PM
list of class instances within a list of a class instances John Wohlbier Python 2 02-22-2004 08:41 AM



Advertisments