
Python membership operators are one of the most practical tools in the language. If you have ever needed to check whether a value exists in a list, string, tuple, set, or dictionary, Python membership operators make that job simple and readable. Instead of writing a manual loop to scan through items, you can use the in and not in operators to express that check in a single clear line — which is exactly the kind of code Python is designed to encourage.
Python provides exactly two membership operators:
in — evaluates to True if the specified value is found in the sequencenot in — evaluates to True if the specified value is NOT found in the sequenceThese operators return a boolean result (True or False) and work with any iterable in Python: lists, tuples, strings, sets, and dictionaries. They are part of Python's comparison operators and are evaluated left to right.
Here is the simplest possible example to see Python membership operators in action:
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits)
print("grape" in fruits)
print("grape" not in fruits)
Output
True
False
True
The in operator scanned the list and returned True for "banana" because it is present, and False for "grape" because it is not. The not in operator is simply the logical inverse — it returns True when the value is absent.
Python membership operators work naturally with strings. When you use in on a string, Python checks whether one string appears as a substring inside another. This is one of the most common string operations in Python.
sentence = "Python is a powerful programming language"
print("powerful" in sentence)
print("Java" in sentence)
print("Java" not in sentence)
Output
True
False
True
String membership testing with in is case-sensitive. The string "python" (lowercase) would not match "Python" (capitalized). This makes the in operator a quick way to search text without needing regular expressions for simple substring checks.
You can also check for individual characters within a string:
word = "membership"
print("m" in word)
print("z" in word)
print("ship" in word)
Output
True
False
True
The Python in operator checks for the presence of any substring — not just single characters. "ship" is a substring of "membership", so it returns True.
Lists and tuples are among the most common places you will use Python membership operators. Lists allow duplicates, and the in operator returns True as long as the value appears at least once anywhere in the list.
scores = [88, 75, 92, 65, 92]
print(92 in scores)
print(100 in scores)
print(100 not in scores)
Output
True
False
True
The same membership test works with tuples in exactly the same way:
colors = ("red", "green", "blue")
print("green" in colors)
print("yellow" not in colors)
Output
True
True
A practical use case for list membership is validating user input against a fixed set of allowed values. This is cleaner and more readable than writing multiple equality checks with or:
allowed_roles = ["admin", "editor", "viewer"]
user_input = "editor"
if user_input in allowed_roles:
print("Access granted")
else:
print("Invalid role")
Output
Access granted
Sets in Python are unordered collections of unique elements. The Python membership test with sets works exactly the same way syntactically as with lists, but the performance characteristic is very different. Sets use hash-based lookups, so checking membership in a set is much faster than scanning a list.
approved_ids = {101, 202, 303, 404}
print(202 in approved_ids)
print(999 in approved_ids)
print(999 not in approved_ids)
Output
True
False
True
For scenarios where you are checking membership repeatedly against a large collection, a set is almost always a better choice than a list. The in operator on a list scans element by element from the start, but on a set it finds the element in constant time regardless of how large the set is.
When you use in with a dictionary, Python checks membership among the keys, not the values. This distinction is important and often catches beginners off guard.
user = {"name": "Alice", "age": 30, "city": "Toronto"}
print("name" in user)
print("Alice" in user)
print("city" not in user)
Output
True
False
False
"Alice" is a value, not a key, so the Python membership test returns False for it. If you want to check whether a value exists anywhere in the dictionary, use .values():
user = {"name": "Alice", "age": 30, "city": "Toronto"}
print("Alice" in user.values())
print(30 in user.values())
print("Berlin" not in user.values())
Output
True
True
True
To check for a specific key-value pair, you can check membership within .items(), which returns tuples of (key, value) pairs:
user = {"name": "Alice", "age": 30, "city": "Toronto"}
print(("name", "Alice") in user.items())
print(("age", 99) in user.items())
Output
True
False
One of the most natural uses of Python membership operators is inside if statements. They make conditions read almost like plain English, which is one of the core principles of Python's design philosophy.
blocked_users = ["spammer123", "badactor", "testbot"]
username = "badactor"
if username in blocked_users:
print(f"{username} is blocked from accessing the system.")
else:
print(f"Welcome, {username}!")
Output
badactor is blocked from accessing the system.
You can combine membership tests with other conditions to create precise filters:
valid_extensions = [".jpg", ".jpeg", ".png", ".gif"]
filename = "photo.png"
ext = filename[filename.rfind("."):]
if ext in valid_extensions:
print("Valid image file")
else:
print("Unsupported file type")
Output
Valid image file
Python membership operators work seamlessly inside loops and list comprehensions, letting you filter collections with concise, readable code. This pattern is used frequently in real Python programs.
all_students = ["Alice", "Bob", "Charlie", "David", "Eve"]
honor_roll = ["Alice", "Charlie", "Eve"]
for student in all_students:
if student in honor_roll:
print(f"{student} is on the honor roll")
Output
Alice is on the honor roll
Charlie is on the honor roll
Eve is on the honor roll
Using a list comprehension, the same filtering logic becomes a single clean expression:
all_students = ["Alice", "Bob", "Charlie", "David", "Eve"]
honor_roll = ["Alice", "Charlie", "Eve"]
honor_students = [s for s in all_students if s in honor_roll]
print(honor_students)
Output
['Alice', 'Charlie', 'Eve']
You can also use not in inside comprehensions to exclude certain values:
all_items = ["apple", "banana", "mango", "cherry", "grape"]
excluded = {"banana", "grape"}
available = [item for item in all_items if item not in excluded]
print(available)
Output
['apple', 'mango', 'cherry']
For lists and tuples, the in operator performs a linear scan — Python goes through each element one by one until it finds a match or exhausts the sequence. For sets and frozensets, Python uses hash-based lookup, so membership testing is constant time. For dictionaries, in checks keys using the same hash approach.
Custom objects can also support the in operator by implementing the __contains__ dunder method. This lets you define what membership means for your own classes:
class NumberRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __contains__(self, value):
return self.start <= value <= self.end
r = NumberRange(1, 10)
print(5 in r)
print(15 in r)
print(0 not in r)
Output
True
False
True
This extensibility is what makes Python membership operators so powerful — any class can define what in means for its instances by implementing __contains__.
This example brings together all the key uses of Python membership operators in a single runnable program — checking lists, strings, sets, and dictionaries, filtering with comprehensions, and using a custom class with __contains__.
# Python membership operators - complete working example
class ScoreBoard:
def __init__(self, top_scores):
self.top_scores = top_scores
def __contains__(self, score):
return score in self.top_scores
def check_membership():
# List membership with in and not in
fruits = ["apple", "mango", "grape", "kiwi", "peach"]
print("List membership:")
print("mango in fruits:", "mango" in fruits)
print("banana in fruits:", "banana" in fruits)
print("banana not in fruits:", "banana" not in fruits)
print()
# String membership - substring check
message = "Python membership operators are powerful"
print("String membership:")
print("'membership' in message:", "membership" in message)
print("'Java' in message:", "Java" in message)
print("'powerful' in message:", "powerful" in message)
print()
# Set membership - fast hash-based lookup
approved_ids = {1001, 1002, 1003, 1004}
print("Set membership:")
print("1002 in approved_ids:", 1002 in approved_ids)
print("9999 in approved_ids:", 9999 in approved_ids)
print("9999 not in approved_ids:", 9999 not in approved_ids)
print()
# Dictionary membership - checks keys by default
config = {"host": "localhost", "port": 8080, "debug": True}
print("Dictionary membership:")
print("'port' in config:", "port" in config)
print("'timeout' not in config:", "timeout" not in config)
print("'localhost' in config.values():", "localhost" in config.values())
print()
# Filtering with list comprehension using not in
all_items = ["apple", "banana", "mango", "cherry", "grape"]
excluded = {"banana", "grape"}
filtered = [item for item in all_items if item not in excluded]
print("Filtered list using not in:", filtered)
print()
# Custom class implementing __contains__
board = ScoreBoard([95, 98, 100, 87, 92])
print("Custom class membership:")
print("98 in board:", 98 in board)
print("70 in board:", 70 in board)
print("70 not in board:", 70 not in board)
check_membership()
Output
List membership:
mango in fruits: True
banana in fruits: False
banana not in fruits: True
String membership:
'membership' in message: True
'Java' in message: False
'powerful' in message: True
Set membership:
1002 in approved_ids: True
9999 in approved_ids: False
9999 not in approved_ids: True
Dictionary membership:
'port' in config: True
'timeout' not in config: True
'localhost' in config.values(): True
Filtered list using not in: ['apple', 'mango', 'cherry']
Custom class membership:
98 in board: True
70 in board: False
70 not in board: True