in: Returns True if a value is found in the sequence.
In Python, the in operator is used for one primary purpose: to check if a value exists within a sequence or collection. This process is called membership testing. You can significantly increase the power of your code by using this operator for highly efficient lookups and by defining its behavior for your own custom classes to create intuitive, readable logic.
1. Membership Testing in Built-in Types
This is the standard use of the in operator. It checks for the presence of an element and returns a boolean value (True or False).
- For Lists, Tuples, and Strings: It checks if an element is present in the sequence.
Python
my_list = ["apple", "banana", "cherry"]
print(f"'banana' in my_list: {'banana' in my_list}")
# Output: True
my_string = "hello world"
print(f"'world' in my_string: {'world' in my_string}")
# Output: True
- For Dictionaries: It checks if a given key exists in the dictionary.
Python
person = {"name": "Neha", "age": 29}
print(f"'age' in person: {'age' in person}")
# Output: True
- For Sets: It performs a highly efficient check for an element's presence.
Python
my_set = {"apple", "banana", "cherry"}
print(f"'apple' in my_set: {'apple' in my_set}")
# Output: True
2. Increasing Power with Efficiency and Operator Overloading (__contains__)
You can make your code more powerful in two main ways: by leveraging the efficiency of sets and dictionaries, and by making your own objects support the in operator.
Efficiency
Checking for membership with in is significantly faster for sets and dictionaries than it is for lists and tuples. If you need to perform many membership checks on a large collection of data, converting it to a set first can dramatically improve your code's performance.
Operator Overloading (__contains__)
You can define the behavior of the in operator for your own custom classes by implementing the __contains__ special method. This allows you to define what it means for an item to be "in" an instance of your class.
Example: Checking for Ingredients in a Recipe
Let's extend the Recipe class from your Canvas. The most intuitive way to check if a recipe contains a certain ingredient is to use the in operator. We can enable this by implementing __contains__.
Python
# --- 1. Define the Custom Class ---
class Recipe:
"""A class to represent a recipe with ingredients and servings."""
def __init__(self, name, servings, ingredients):
"""
The constructor for the class.
Ingredients is a dictionary.
"""
self.name = name
self.servings = servings
self.ingredients = ingredients
def __repr__(self):
"""
Provides a developer-friendly string representation of the object.
"""
return (f"Recipe(name='{self.name}', servings={self.servings})")
def __contains__(self, ingredient_name):
"""
This is the special method that defines the behavior of the 'in' operator.
It checks if an ingredient is present in the recipe's ingredient list.
"""
# Return True if the ingredient_name is a key in our ingredients dictionary.
return ingredient_name in self.ingredients
# --- 2. Create an Instance of the Class ---
cake_recipe = Recipe(
name="Chocolate Cake",
servings=8,
ingredients={"flour_grams": 200, "sugar_grams": 150, "eggs": 4}
)
# --- 3. Use the 'in' Operator on our Custom Object ---
# Because we defined the __contains__ method, we can now use the 'in' operator
# in a very natural and readable way.
if "sugar_grams" in cake_recipe:
print("The recipe contains sugar.")
else:
print("The recipe does not contain sugar.")
if "butter_grams" in cake_recipe:
print("The recipe contains butter.")
else:
print("The recipe does not contain butter.")
not in: Returns True if a value is not found in the sequence.
In Python, the not in operator is used for one primary purpose: to check if a value does not exist within a sequence or collection. It is the direct opposite of the in operator. You can increase the power of your code by using this operator for clear, readable conditional logic and by defining its behavior for your own custom classes.
1. Membership Testing in Built-in Types
This is the standard use of the not in operator. It checks for the absence of an element and returns a boolean value (True or False).
- For Lists, Tuples, and Strings: It checks if an element is absent from the sequence.
Python
my_list = ["apple", "banana", "cherry"]
print(f"'mango' not in my_list: {'mango' not in my_list}")
# Output: True
For Dictionaries: It checks if a given key does not exist in the dictionary.
Python
person = {"name": "Neha", "age": 29}
print(f"'email' not in person: {'email' not in person}")
# Output: True
2. Increasing Power with Readability and Operator Overloading (__contains__)
You can make your code more powerful in two main ways: by writing more readable conditional statements and by making your own objects support the not in operator.
Readability
Using not in makes your code more readable and closer to natural language. The expression if item not in my_list: is much clearer than the alternative if not (item in my_list):.
Operator Overloading (__contains__)
You don't need to define a separate method for not in. If you have already implemented the __contains__ special method (which defines the behavior for the in operator), Python will automatically use the opposite of its result for not in.
Example: Checking for Missing Ingredients in a Recipe
Let's use the Recipe class from your Canvas. By defining __contains__, we automatically get the functionality for not in, allowing us to write powerful and intuitive checks.
Python
# --- 1. Define the Custom Class ---
class Recipe:
"""A class to represent a recipe with ingredients and servings."""
def __init__(self, name, servings, ingredients):
"""
The constructor for the class.
Ingredients is a dictionary.
"""
self.name = name
self.servings = servings
self.ingredients = ingredients
def __repr__(self):
"""
Provides a developer-friendly string representation of the object.
"""
return (f"Recipe(name='{self.name}', servings={self.servings})")
def __contains__(self, ingredient_name):
"""
This is the special method that defines the behavior of the 'in' operator.
Python will automatically use its inverse for the 'not in' operator.
"""
# Return True if the ingredient_name is a key in our ingredients dictionary.
return ingredient_name in self.ingredients
# --- 2. Create an Instance of the Class ---
cake_recipe = Recipe(
name="Chocolate Cake",
servings=8,
ingredients={"flour_grams": 200, "sugar_grams": 150, "eggs": 4}
)
# --- 3. Use the 'not in' Operator on our Custom Object ---
# Because we defined the __contains__ method, we can now use 'not in'
# in a very natural and readable way.
if "butter_grams" not in cake_recipe:
print("The recipe does not contain butter. You might need to add it!")
else:
print("The recipe contains butter.")