in
Is it in there? One operator for elements, substrings and dict keys.
Common call
if key in d:
Returns
bool
Replaces
"ell" in "hello" — substring, not element
Watch out
dicts test keys, not values — use d.values() for values
itemitem — The candidate — compared with == against elements (substring match for strings).type: Any · required in containercontainer — Where to look: list, tuple, set, dict (keys), str, or any __contains__/iterable.type: iterable · required
→ bool
Demo
Live evaluation
Try:
Inputs
itemAnyto find
containerlistcomma-separated items
Output
'b' in ['a', 'b', 'c']
True
Membership by equality against a list here. In real Python the same operator does substring tests on strings ("ell" in "hello") and key tests on dicts.
Operands
| Name | Type | Required | Description |
|---|---|---|---|
| item | Any | yes | The candidate — compared with == against elements (substring match for strings). |
| container | iterable | yes | Where to look: list, tuple, set, dict (keys), str, or any __contains__/iterable. |
Return value
bool — True when item is an element of container — or a substring, for strings. Dicts test their KEYS.
Common patterns
Key check before access
The safe-dict pattern (or use .get).
if name in scores: print(scores[name])
Value whitelists
Sets make repeated membership checks O(1).
VALID = {"a", "b", "c"} if code in VALID:
Substring search
The readable alternative to find() != -1.
if "@" in email:
Examples
1. List element
2 in [1, 2, 3]
Returns
True2. Substring
"ell" in "hello"
Returns
True3. Dict tests keys
"a" in {"a": 1}
Returns
True4. Not values
1 in {"a": 1}
Returns
FalsePitfalls
1. Dicts test keys, not values
The most common in-operator surprise.
False
1 in {"a": 1}
False — 1 is a value, not a key
Fix
1 in {"a": 1}.values()
True
2. List membership is O(n)
Hot-loop membership wants a set.
Slow
for x in stream: if x in big_list:
scans the list every time
Fix
big = set(big_list) for x in stream: if x in big:
O(1) per check
3. Substring vs element for strings
"ab" in "abc" is True even though "ab" is not a single character.
Element intuition
"ab" in list("abc")
False — list of chars has no "ab"
Substring is on str
"ab" in "abc"
True
When to use
Use it
- Membership and key checks
- Substring tests
- Whitelist validation (with sets)
Reach for something else
- Position needed → list.index / str.find
- Repeated checks against a big list → convert to set
Notes
Complexity
O(1) sets/dicts; O(n) lists/tuples; O(n·m) strings
Return
bool
CPython impl
ceval COMPARE_OP/CONTAINS_OP → __contains__, falls back to iteration
Memory
No allocation
Thread-safe
Yes for stable containers
FAQ
Python tries __contains__, then falls back to iterating __iter__ comparing with ==. Implement __contains__ for O(1) or custom semantics.
History
1.0
Core operator from the beginning.