Membership Operators
Python · Operators
Theory
in and not in test whether a value is contained in a collection and return True or False. 'Mumbai' in cities checks every list element with ==. On strings, in looks for a substring, so 'umb' in 'Mumbai' is True. On a dictionary, in checks the keys, not the values: 'name' in employee is True but 'Asha' in employee is False; use 'Asha' in employee.values() for values.
Speed depends on the container. A list or tuple is scanned item by item, so the time grows with its length (O(n)). A set or dict hashes the value and jumps straight to where it would be stored, which takes roughly constant time no matter how big it is (average O(1)). That is why converting a big list of IDs to a set before many lookups can make code dramatically faster. in raises TypeError if the right side is not a container (5 in 10) or if you search a set for an unhashable value like a list.
Why we use it
Checking 'is this item already there?' is everywhere: valid status codes, blocked users, duplicate IDs, allowed file types. in expresses it in one readable line without writing a loop.
When to use it
Use in for any containment check. For many lookups against the same large collection, store it as a set or dict first. Use not in for exclusion checks; it reads better than not (x in y).
How it works
- Evaluate 'Mumbai' in cities
- Is cities a set or dict? Yes: Hash 'Mumbai' and check that slot directly. No: Scan items one by one from the start.
- Did some item compare equal? Yes: Return True and stop scanning. No: Return False after the last item.
- print shows True
Syntax
value in sequence
value not in sequenceExample
cities = ['Mumbai', 'Delhi']
print('Mumbai' in cities)Key points
- Works on lists, tuples, sets, strings, and dict keys
- On a dict it checks keys; use .values() to search values
- On strings it finds substrings: 'umb' in 'Mumbai' is True
- Lists are scanned O(n); sets and dicts are hashed, average O(1)
- Raises TypeError if the right side is not a container, e.g. 5 in 10