Searching in custom classes contains and iter

suggest change

To allow the use of in for custom classes the class must either provide the magic method __contains__ or, failing that, an __iter__-method.

Suppose you have a class containing a list of lists:

class ListList:
    def __init__(self, value):
        self.value = value
        # Create a set of all values for fast access
        self.setofvalues = set(item for sublist in self.value for item in sublist)
        
    def __iter__(self):
        print('Using __iter__.')
        # A generator over all sublist elements
        return (item for sublist in self.value for item in sublist)
        
    def __contains__(self, value):
        print('Using __contains__.')
        # Just lookup if the value is in the set
        return value in self.setofvalues
# Even without the set you could use the iter method for the contains-check:
# return any(item == value for item in iter(self))

Using membership testing is possible using in:

a = ListList([[1,1,1],[0,1,1],[1,5,1]])
10 in a    # False
# Prints: Using __contains__.
5 in a     # True
# Prints: Using __contains__.

even after deleting the __contains__ method:

del ListList.__contains__
5 in a     # True
# Prints: Using __iter__.

Note: The looping in (as in for i in a) will always use __iter__ even if the class implements a __contains__ method.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents