Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom class object and "in" set operator

Tags:

python

I'm using Python 3.6. Suppose that I'm trying to keep a unique set of tuples. I know I can use tuple in set and get back the correct result (the set contains the tuple or not).

s = set()
t1 = (1, 2)
t2 = (1, 2)
s.add(t1)
print(t2 in s) # True -- Great!

Now, suppose I have a custom class that contains a tuple. I would like to define uniqueness for the custom class objects as uniqueness for the tuple. I did the following:

class TupleWrapper(object):

    def __init__(self, t):
        self.t = t # tuple

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


s = set()
t1 = TupleWrapper((1, 2))
s.add(t1)
t2 = TupleWrapper((1, 2))
print(t2 in s) # False -- WHY?

I wrote my own __hash__() method that hashes the tuple. So why are the two TupleWrapper objects with the same tuple not found to be the same in the set? Do I need to override another method?

like image 890
stackoverflowuser2010 Avatar asked Dec 02 '25 06:12

stackoverflowuser2010


1 Answers

you need to implement __eq__ on TupleWrapper as well.

def __eq__(self, other):
    if isinstance(other, TupleWrapper):
        return self.t == other.t
    return NotImplemented

otherwise, when checking to see if the object is already in the set, it will default to identity comparison, which is just is (i.e., t1 is t2 or id(t1) == id(t2)).

more detail: loosely speaking, on insertion, set (and dict) first use the hash value to figure out which bucket things are in. then, in that bucket, it uses == to check, in the case of a hash collision, if that object is already there.

hash documentation here

like image 185
acushner Avatar answered Dec 03 '25 19:12

acushner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!