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"
Summary. Implement the Python __eq__ method to define the equality logic for comparing two objects using the equal operator ( == )
The set() function creates a set object. The items in a set list are unordered, so it will appear in random order. Read more about sets in the chapter Python Sets.
The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory. In the vast majority of cases, this means you should use the equality operators == and != , except when you're comparing to None .
To check if the Set contains an element in Python, use the in keyword, which returns True if the specified Set contains an element and False otherwise. The in keyword checks if the item is present in a sequence like a list, range, string, set, etc.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With