Why is a duplicate object being added to my Python set when it shouldn't be?
python, set
Solution
Your hash function is grossly ineffective. Python requires that your `__hash__` function should return the same value for two objects that are considered equal, but yours doesn't. From the `object.__hash__` documentation:
The only required property is that objects which compare equal have the same hash value
`repr(self)` returns the default representation, which uses the object id. It'll basically return a different hash based on object identity. You may as well have done:
return hash(id(self))
That's not a good hash as that values differs between all instances. As a result your `hash()` values fail to meet the required property:
>>> a = Question('foo', 'bar')
>>> b = Question('foo', 'bar')
>>> a == b
True
>>> hash(a) == hash(b)
False
You need to hash your attributes instead:
return hash(self.title + self.answer)
Now the hash is based on the same values that inform equality.
Problem
I have a class definition of this: ``` class Question: title = "" answer = "" def __init__(self, title, answer): self.title = title self.answer = answer def __eq__(self, other): return self.title == other.title and self.answer == other.answer def __hash__(self): return hash(repr(self)) ``` and I'm trying to add many of these objects to a set, only if the object does not have the same properties as any of the other objects already in the set: ``` questionset = set() q = Question(questionparts[0] + questionparts[1], questionparts[2]) if q not in questionset: questionset.add(q) ``` If I have two questions, each with the same property values, I expect only one to get added to my set, instead my set has a length of 2. What am I doing wrong? If I log each question object, I can confirm the items have the same property values.