Rich comparison methods don't work in sets?

Chris Rebert clp2 at rebertia.com
Fri Jun 19 15:42:49 EDT 2009


On Fri, Jun 19, 2009 at 12:02 PM, Gustavo Narea<me at gustavonarea.net> wrote:
> Hello, everyone.
>
> I've noticed that if I have a class with so-called "rich comparison"
> methods
> (__eq__, __ne__, etc.), when its instances are included in a set,
> set.__contains__/__eq__ won't call the .__eq__ method of the elements
> and thus
> the code below:
> """
> obj1 = RichComparisonClass()
> obj2 = RichComparisonClass()
>
> set1 = set([obj1])
> set2 = set([obj2])
>
> if obj1 == obj2:
>    print "Objects 1 and 2 are equivalent"
> else:
>    print "Objects 1 and 2 aren't equivalent"
>
> if set1 == set2:
>    print "Sets 1 and 2 are equivalent"
> else:
>    print "Sets 1 and 2 aren't equivalent"
> """
>
> Would output:
> """
> Objects 1 and 2 are equivalent
> Sets 1 and 2 aren't equivalent
> """
>
> instead of:
> """
> Objects 1 and 2 are equivalent
> Sets 1 and 2 are equivalent
> """
>
> How can I work around this? The only solution that comes to my mind is

Note that sets are dict-based and thus use hash tables internally.
Thus, you must implement a sensible __hash__ method.
The default __hash__ provided by class `object` uses the object ID for the hash.

Since id(x) == id(y)  iff  x is y, and
hash(x) != hash(y) implies x != y,
If you don't implement __hash__, object's implementation causes every
distinct object of your type to be considered unequal a priori, so it
doesn't bother to check any further by calling the comparison methods.

Cheers,
Chris
-- 
http://blog.rebertia.com



More information about the Python-list mailing list