Rich comparison methods don't work in sets?

Robert Kern robert.kern at gmail.com
Sat Jun 20 16:54:14 EDT 2009


On 2009-06-20 11:27, MRAB wrote:
> Gustavo Narea wrote:
>> Hello again, everybody.
>>
>> Thank you very much for your responses. You guessed right, I didn't
>> use the __hash__ method (and I forgot to mention that, sorry).
>>
>> And unfortunately, I think I can't make them hashable, because the
>> objects are compared based on their attributes, which are in turn
>> other kind of objects compared based on other attributes. All these
>> class instances are compared with __eq__/__ne__ and they wrap
>> relatively complex data which would be hard to attempt to represent
>> them unambiguously using a 32-bit integer. That's why I'm afraid I
>> cannot use hashables.
>>
>> I guess I'll have to use something like the function of my first
>> post. :(
>>
> A hash doesn't have to be unambiguous. It's just a way to reduce the
> number of equality checks that have to be made.
>
> Could you create a hash from a tuple of attributes?

A typical way to implement this is to make a method that returns a tuple of 
attributes to use in both the __eq__ and __hash__ methods.

class Foo(object):

   def key(self):
     return (self.x, self.y, self.bar)

   def __eq__(self, other):
     return self.key() == other.key()

   def __ne__(self, other):
     return not (self == other)

   def __hash__(self):
     return hash(self.key())


As long as those attributes are also hashable, this usually works well.

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list