How is membership testing different for list and recruitment?

I am having trouble figuring out why the first of these statements is OK and the second is causing an error.

subject_list = [Subject("A"), Subject("B"), Subject("C")] subject_set = set() subject_set.add(Subject("A")) subject_set.add(Subject("B")) subject_set.add(Subject("C")) self.assertIn(Subject("A"), subject_list) self.assertIn(Subject("A"), subject_set) 

Here is the error:

 Traceback (most recent call last): File "C:\Users\...\testSubject.py", line 34, in testIn self.assertIn(Subject("A"), subject_set) AssertionError: <Subject: A> not found in set([<Subject: B>, <Subject: C>, <Subject: A>]) 

The equality test in the Subject class is just self.name == other.name , and in another UnitTest I check that Subject("A") == Subject("A") . I really can’t understand why the topic is on the list and not on the set. Ideally, I would like the theme to be in both.

+8
python list set member
source share
4 answers

Expression

 Subject("A") in subject_list 

will compare Subject("A") with each entry in subject_list using the Subject.__eq__() method. If this method is not overwritten, by default it always returns False if both operands are not the same object. The above expression always returns False if Subject does not have the __eq__() method, since Subject("A") is a new instance that can no longer be in the list.

Expression

 Subject("A") in subject_set 

on the contrary, it will first use Subject.__hash__() to find the bucket, and use Subject.__eq__() only after that. If you did not define Subject.__hash__() in a manner compatible with Subject.__eq__() , this will not work.

+11
source share

Membership in the set also depends on the hash of the object, and therefore you must implement the __hash__() method in the class accordingly.

+4
source share

Either you don't have the __hash__() method in your Subject class, or it is dodgy. Try the following:

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

The docs are here .

+3
source share

To use them in a set, you need to make sure that Subject hashes properly. If you do not define __hash__ yourself, it will just take id , and that will be different for different instances. __hash__ must be defined so that equal objects have equal hashes.

+2
source share

All Articles