Rich comparison methods don't work in sets?

Aaron Brady castironpi at gmail.com
Fri Jun 19 23:00:49 CEST 2009


On Jun 19, 12:42 pm, Chris Rebert <c... at rebertia.com> wrote:
> On Fri, Jun 19, 2009 at 12:02 PM, Gustavo Narea<m... 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:
snip

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

You're using sets for uniqueness and faster lookups than a list or
other collection.  Uniqueness is determined by hash key first, then by
identity (due to an idiosyncrasy of 'RichCompareBool'), then by rich
equality.  If you want to compare to every element, you can't use
sets, because they take short-cuts by omitting many of the
comparisons.



More information about the Python-list mailing list