How to implement __eq__ for set inclusion test?
equality, python, set
Solution
From the documentation on sets:
The set classes are implemented using dictionaries. Accordingly, the requirements for set elements are the same as those for dictionary keys; namely, that the element defines both __eq__() and __hash__().
The __hash__ function documentation suggests xor-ing the hashes of components together. As others have mentioned, it's generally not a good idea to hash mutable objects, but if you really need to, this works:
class DummyObj(object):
...
def __hash__(self):
return (hash(self.myTuple) ^
hash(tuple(self.myList)) ^
hash(tuple(self.myDictionary.items())))
And checking to see if it works:
p1 = DummyObj(t1, list1, d1)
p2 = DummyObj(t1, list1, d1)
mySet = set()
mySet.add(p1)
print "p1 in set", p1 in mySet
print "p2 in set", p2 in mySet
This prints:
$ python settest.py
p1 in set True
p2 in set True
Problem
I am running into an issue where I'm adding an instance to a set and then later testing to see whether or not that object exists in that set. I've overridden `__eq__()` but it doesn't get called during the inclusion test. Do I have to override `__hash__()` instead? If so, how would I implement `__hash__()` given that I need to hash the tuple, the list, and the dictionary? ``` class DummyObj(object): def __init__(self, myTuple, myList, myDictionary=None): self.myTuple = myTuple self.myList = myList self.myDictionary = myDictionary def __eq__(self, other): return self.myTuple == other.myTuple and \ self.myList == other.myList and \ self.myDictionary == other.myDictionary def __ne__(self, other): return not self.__eq__(other) if __name__ == '__main__': list1 = [1, 2, 3] t1 = (4, 5, 6) d1 = { 7 : True, 8 : True, 9 : True } p1 = DummyObj(t1, list1, d1) mySet = set() mySet.add(p1) if p1 in mySet: print "p1 in set" else: print "p1 not in set" ```