Python Membership Operators

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.

What Are Python Membership Operators

Python provides exactly two membership operators:

  • in — evaluates to True if the specified value is found in the sequence
  • not in — evaluates to True if the specified value is NOT found in the sequence

These 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 in Operator with Strings

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.

Membership Operators with Lists and Tuples

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

Membership Operators with Sets

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.

Membership Operators with Dictionaries

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

Membership Operators in Conditional Statements

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

Using Membership Operators in Loops and List Comprehensions

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']

How Python Implements Membership Operators Internally

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__.

Full Working Example

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