One of the key features that make Python so user-friendly is its simple but effective membership operators — “in” and “not in“. These operators allow developers to quickly and easily check for membership in various data structures such as lists, tuples, dictionaries, and strings.
The “in” and “not in” membership operators in Python evaluate whether a specified value is present in a collection of values, returning a boolean result of either True or False. For instance, you can use the “in” operator to search for a specific element within a list or to verify if a certain substring exists in a larger string.
These operators are integral to software development, as they streamline the process of comparing and manipulating data within different data structures. By understanding and utilizing these operators properly, you can enhance the performance and readability of your code and improve your programming skills.
So, let’s take a look under the hood of these operators.
Python “in” Keyword and Membership Operators
The in keyword actually serves two purposes in the Python language. We can use it as a membership operator, and we can also use it in a for loop to assign each item in an iterable to a variable.
In this article, we’ll be focusing on in as a membership operator.
Python provides two important membership operators, in and not in, to check if a value is a member of a sequence or not. A sequence can be a list, tuple, string, or even dictionaries and sets.
In this section, we’ll explore the usage and examples of these two operators.
1. The “in” Operator
The in operator is used to determine if a specified value is a member of a sequence (list, tuple, string, etc.). If the value is a member of the sequence, it returns True, otherwise, it returns False.
Let’s take a look at the in operator in these examples:
my_list = [1, 2, 3, 4, 5]
print(3 in my_list)
Output:
True
Let’s go over another example:
food = ["greens", "ham", "eggs"]
print('rice' in food)
Output:
False
In the first example, the in operator returns True because the number 3 is part of the list. However, in the second example, it returns False because rice is not in the food list.
So, the in operator provides a short and concise way to test for membership. The alternative would be to write a lengthy membership test method to check iterable data types.
Let’s look at an example:
def is_member(value, sequence):
for item in sequence:
if item == value:
return True
return False
print(is_member(3, [1, 2, 3, 4, 5]))
So, we can see that using the in operator makes your code much shorter, easier to read, and more efficient.
2. The “not in” Operator
The not in operator works similarly to the in operator, but returns True when the specified value is not a member of the sequence and False otherwise.
Here are some examples of using the not in operator:
my_list = [1, 2, 3, 4, 5]
places = ['london', 'istanbul', 'tokyo' ]
print(4 not in my_list)
print('London' not in places)
Output:
False
True
The first example returns False because the integer 4 is present in the list my_list. The second example returns True, because ‘London’ is not in the list places.
Note: Both the in and not in operators are case-sensitive as we can see in the second example.
How to Use “in” and “not in” With Different Data Types
In the previous examples, we used the membership operators to check against values stored in lists. However, lists are not the only data types that are compatible with these operators.
We can use them to check for membership in various iterable data types in the Python language. Let’s look at them:
1. Strings
Strings are one of the fundamental data types in Python. We can iterate over them with a for loop because their values are stored sequentially in memory.
As a result, we can use the in and not in operators to search for sub-strings in a target string. Let’s look at some examples:
print('j' in 'john')
print('red' not in 'The stallions were bred to be racers')
print('car' in 'I have eaten too may carbs today')
Output:
True
False
True
The first example returns True because the character j is in the string john. The second one returns False, because the sub-string red can be found in the word bred.
The last example returns True because the sub-string car is present in the word carbs.
2. Lists, Tuples, and Sets
Lists, tuples, and sets are common Python iterable data types that you can store values in. Sets allow you to store only unique values, while tuples are immutable which means you can’t modify their elements after initialization.
You can learn more about their differences in our article on Python Set vs List.
We can use the in and not in operators to perform membership tests on all three of these data structures. Let’s look at an example:
sports = ('tennis', 'football', 'volleyball')
fruits = ['apple', 'blackberry', 'blueberries', 'apple']
names = {'Alex', 'James', 'Mikel'}
print('football' in sports)
print('bluberry' not in fruits)
print('alex' in names)
Output:
True
True
False
You can even combine two of these datatypes and use them with the membership operators.
ranks = [('John', 'gm'), ('Alice', 'fm'), ('Kabir', 'im)]
print(('John', 'gm') in ranks)
Output:
True
In this example, we checked to see if a tuple was a member of a list of tuples.
3. Range
The range function produces a sequence of numbers in a specified range. We can use the in and not in operators to perform membership checks on these values.
Let’s demonstrate this with an example:
print(4 in range(7))
print(5 in range(2, 20, 2))
Output:
True
False
The first example will return True because 4 is in the range of values, while the second returns False because 5 isn’t present in that range. Membership operators are useful when dealing with ranges because the step value might not be known during real-life applications.
So, by using the operators, we can perform quick membership tests.
4. Dictionaries
A dictionary is a Python data structure that stores items in key-value pairs. We can use the in and not in operators to perform membership checks on the dictionary’s keys.
For example:
animals = {'dog': 'mammal', 'cat':'mammal', 'salmon':'fish'}
print('salmon' in animals)
print('mammal' in animals)
Output:
True
False
The first query returns True because Salmon is a key in the dictionary. However, the second option returns False, because mammal is a value, not a key.
For the in operator to access the dictionary’s values, we can use the values() function.
print('mammal' in animals.values())
This will return True. You can check out a great use case in this video on How To Build A Google News Aggregator In Power BI Using Python:
We can use membership operators to check for certain keywords in the scraped data.
We can also search for key-value pairs in dictionaries using the items() function.
print({'liger': 'mammal'} not in animals.items())
As you see, we checked for both the key and its value in the animals dictionary.
In summary, the in and not in operators allow you to easily check for membership in Python sequences. They can make your code more concise and easy to read when working with lists, strings, tuples, sets, and dictionaries
How to Implement “in” and “not in” in Python Classes
Python provides a special dunder function that you can use in implementing membership tests in your classes. This way, you can perform membership checks on instances of your class.
This special function is the __contains__() method. Let’s take a look at how it works
class Cat:
def __contains__(self, other):
print(other, " is a cat.")
a = Cat()
'maine coone' in a
If we run it, we see that it returns ‘maine coone is a cat‘ when we try to use the in operator on a class instance. It also returns False by default since we didn’t specify a return value.
Let’s look at a more realistic example. Suppose we have a class whose instances have the names of athletes and the sports they play in a tuple.
Now, we want the in operator to check the sports tuple for a given value. Let’s implement it;
class Athlete:
def __init__(self, name, sports):
self.name = name
self.sports = sports
def __contains__(self, other):
return other in self.sports
a = Athlete('Anita', ('volleyball', 'chess', 'basketball'))
print('soccer' in a)
print('chess' in a)
Output:
False
True
In the code above, we implemented the __contains__() method for class instances of the Athlete class. Now, we can perform membership checks on their list of sports using the in and not in operators.
Final Thoughts
To sum it up, the “in” and “not in” membership operators in Python are essential components of any programmer’s toolkit. They provide a concise and elegant way to check for membership within sequences, helping you build efficient and effective code.
By harnessing the power of these operators, you can simplify your logic, improve performance, and create more robust and intuitive Python programs. So remember to leverage the versatility of “in” and “not in” to your advantage and unlock the full potential of your Python projects.
For more interesting Python features and operators, be sure to check out our Python Cheat Sheet!
Frequently Asked Questions
What is the Time Complexity of Membership Operators?
The time complexity of membership operators depends on the datatype it is checking. For lists, strings, dictionary VALUES, and tuples, it is O(n).
This means it will get slower as the number of the iterable’s elements increases.
However, for sets and dictionary KEYS, the time complexity is O(1). This means the execution time doesn’t depend on the size of the iterable’s elements.
That’s why these data types are used in data science, web development, and other performance-sensitive applications.
Do Membership Operators Work With Functions?
Yes, they can work with functions. As long as the function returns an iterable data type, we can perform a membership check on it.
Let’s look at an example:
def modul3(num):
return [i%3 for i in num]
print(1 in modul3([2, 7, 9]))
Output:
True