Get item from set

Peter Otten __peter__ at web.de
Wed Apr 29 17:53:43 CEST 2009


Aahz wrote:

> In article <gt8v37$kib$03$2 at news.t-online.com>,
> Peter Otten  <__peter__ at web.de> wrote:
>>Aahz wrote:
>>> In article <gt1kb7$jqg$03$1 at news.t-online.com>,
>>> Peter Otten  <__peter__ at web.de> wrote:
>>>>
>>>>Here's a trick to find the actual element. I think Raymond Hettinger
>>>>posted an implementation of this idea recently, but I can't find it at
>>>>the moment.
>>> 
>>> Your code is inverted from Raymond's:
>>
>>I can't see the inversion.
> 
> You were wrapping the objects inserted into the set; Raymond's trick
> involved only wrapping the comparison object.  It's therefore much more
> convenient.

I think you are misreading my code. I took the items (of class X) as they 
were specified by the OP.

The reason I changed their __eq__() method is not that I did not understand 
Raymond's trick, but rather a quirk in the set's item lookup:

>>> class A(object):
...     def __init__(self, value):
...             self.value = value
...     def __hash__(self):
...             return hash(self.value)
...     def __eq__(self, other):
...             return self.value == other.value
...
>>> item = A("a")
>>> container = map(A, "abc")
>>> from get_equivalent import get_equivalent
TestResults(failed=0, attempted=0)

get_equivalent() is Raymond's implementation from the recipe. Let's try it:

>>> get_equivalent(container, item)
<__main__.A object at 0x2091e50>
>>> _ is not item
True

Works. Now the same with a set:

>>> container = set(container)
>>> print get_equivalent(container, item)
None

Oops.

wanted in some_list

performs wanted.__eq__(candidate) 

where candidate is an item in the list.

wanted in some_set

tries

candidate.__eq__(wanted) 

first. You must ensure that this fails in an orderly manner for

wanted.__eq__(candidate)

to be tried at all:

>>> def __eq__(self, other):
...     if not isinstance(other, A):
...             return NotImplemented
...     return self.value == other.value
...
>>> A.__eq__ = __eq__
>>> print get_equivalent(container, item)
<__main__.A object at 0x2091e50>
>>> _ is not item
True

Peter




More information about the Python-list mailing list