Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement __eq__ for set inclusion test?

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"
like image 994
RobertJoseph Avatar asked Mar 10 '13 20:03

RobertJoseph


People also ask

What is the __ eq __ method?

Summary. Implement the Python __eq__ method to define the equality logic for comparing two objects using the equal operator ( == )

What is set () in Python?

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.

How do you define equal in Python?

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 .

How do you find the element of a set in Python?

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.


1 Answers

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
like image 147
jterrace Avatar answered Sep 23 '22 10:09

jterrace