Gere
Gere

Reputation: 12697

Contains test for python objects

How does Python __contains__ work for lists if I use arbitrary objects for elements? Will it revert to the is operator? Or does it use __eq__ if provided?

A simple test gave

class Test: pass

print(Test() in [Test()]) # -> no
a=Test() 
print(a in [a])   # -> yes
print(a in [Test()])  # -> no

So can I assume it uses the comparison by references is?

Upvotes: 1

Views: 103

Answers (2)

user647772
user647772

Reputation:

See the documentation of object.__contains__(self, item):

Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.

For objects that don’t define __contains__(), the membership test first tries iteration via __iter__(), then the old sequence iteration protocol via __getitem__(), see this section in the language reference.

Upvotes: 1

jsbueno
jsbueno

Reputation: 110301

The default __contains__ implementation for list just compares the object with the == (__eq__) operator. It is this operator that, if not defined for a class, defaults to the behavior of is.

In short, "a in lst" is the equivalent to:

def contains(obj, lst):
   for item in lst:
       if obj == lst: 
          return True
   return False

contains(a, lst)

The behavior of == does change whether item implements __eq__ explicitly, and defaults to object identity (is) otherwise.

Upvotes: 3

Related Questions