How to get the intersection of two lists in Python
Learn how to find the intersection of two lists in Python. Explore various methods, tips, real-world uses, and common error fixes.
.png)
The intersection of two lists in Python identifies common elements. This is a frequent task in data manipulation and a fundamental operation for many programming scenarios.
In this article, you'll learn several techniques, from simple loops to efficient set operations using &. You'll also get practical tips, see real-world applications, and receive debugging advice.
Using set() and the & operator
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
intersection = list(set(list1) & set(list2))
print(intersection)--OUTPUT--[4, 5]
This method is highly efficient for finding common elements. By converting the lists to sets with set(), you leverage a data structure optimized for uniqueness and fast membership testing. This approach is much quicker than iterating through lists, especially for large datasets.
The ampersand (&) operator performs the mathematical set intersection, identifying only the elements present in both sets. Finally, list() converts the resulting set back into a list, preserving the original data format while giving you the performance benefits of sets.
Basic intersection techniques
While the & operator is a concise way to intersect sets, you can achieve the same result with other built-in functions and classic Python idioms.
Using the set.intersection() method
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
intersection = list(set(list1).intersection(list2))
print(intersection)--OUTPUT--[4, 5]
The set.intersection() method is a more descriptive alternative to the & operator. Instead of a symbol, you call a method on one set and pass the other as an argument. This approach can make your code's intent clearer, especially for developers who might not be as familiar with Python's set operators.
- Functionally, it's identical to using the
&operator to find common elements. - The choice between them often comes down to personal or team coding style preference.
Using list comprehension
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
intersection = [item for item in list1 if item in list2]
print(intersection)--OUTPUT--[4, 5]
List comprehension offers a concise and highly readable way to find common elements. It builds a new list by iterating through each item in list1 and including it only if that item also exists in list2.
- This method reads almost like plain English, making your code's intent clear.
- While elegant, it's less performant than set-based approaches for large lists because checking for an item
in list2is slower than a set lookup.
Using the filter() function
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
intersection = list(filter(lambda x: x in list2, list1))
print(intersection)--OUTPUT--[4, 5]
The filter() function offers a functional programming approach. It applies a testing function to each element in list1, keeping only the items that pass the test and discarding the rest.
- The test is a
lambdafunction,lambda x: x in list2, which checks if an element from the first list also exists in the second. - Because
filter()returns an iterator—a memory-efficient object—you must convert it back to a list usinglist()to see the final result.
Advanced intersection techniques
For more complex challenges—like working with numerical arrays, preserving duplicates, or comparing custom objects—you'll need to move beyond the standard intersection methods.
Using numpy for efficient numerical intersections
import numpy as np
array1 = np.array([1, 2, 3, 4, 5])
array2 = np.array([4, 5, 6, 7, 8])
intersection = np.intersect1d(array1, array2)
print(intersection)--OUTPUT--[4 5]
When you're working with numerical data, especially in large arrays, the numpy library offers a powerful solution. The np.intersect1d function is specifically designed to find common elements between two numpy arrays, and it's much faster than standard Python list methods for this task.
- This function is highly optimized for numerical computations because
numpy's underlying operations are written in C. - It returns a new, sorted array containing only the unique elements present in both of the original arrays.
Preserving duplicates with collections.Counter
from collections import Counter
list1 = [1, 2, 3, 4, 4, 5]
list2 = [4, 4, 5, 5, 6, 7]
counter1, counter2 = Counter(list1), Counter(list2)
intersection = list((counter1 & counter2).elements())
print(intersection)--OUTPUT--[4, 4, 5]
When you need an intersection that respects duplicates, collections.Counter is the perfect tool. Unlike sets, which only track unique items, a Counter creates a frequency map for each list, counting how many times each element appears.
- The intersection operator (
&) compares these two maps and keeps the minimum count for each common element. - Finally, the
.elements()method expands this result back into a list, giving you an intersection that includes duplicates up to their lowest frequency across both lists.
Intersecting lists of custom objects
class Person:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
p1, p2 = Person("Alice"), Person("Bob")
list1, list2 = [p1, p2], [Person("Alice"), Person("Charlie")]
intersection = list(set(list1) & set(list2))
print([person.name for person in intersection])--OUTPUT--['Alice']
To find common elements in lists of custom objects, you need to tell Python how to determine equality. This is where two special "dunder" methods come into play, allowing you to use standard set operations on your objects.
- The
__eq__method defines what makes two objects equal. In this case, it considers twoPersonobjects the same if theirnameattributes match. - The
__hash__method makes an object hashable, which is a requirement for it to be included in aset.
Once you've implemented these methods, you can convert your lists to sets and find the intersection just as you would with numbers or strings.
Move faster with Replit
Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. Describe what you want to build, and Agent 4 handles everything—from writing the code to connecting databases and APIs, to deploying it live.
Instead of piecing together techniques, you can describe the app you want to build and let the Agent take it from idea to working product:
- A social media tool that compares two lists of usernames to find mutual followers.
- A data-cleaning utility that uses
numpy.intersect1dto efficiently find common IDs between two large datasets. - An inventory app that uses
collections.Counterto compare stock lists from two warehouses and find their common items based on the minimum shared quantity.
Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
Even with the right methods, you might run into a few common pitfalls when finding list intersections in Python.
You'll hit a TypeError if you try to use set() on lists containing unhashable items like other lists or dictionaries. Sets require their elements to be immutable—meaning they can't be changed—but lists and dictionaries are mutable. To fix this, you can convert each mutable item into an immutable equivalent, such as turning inner lists into tuples, before creating the sets.
When working with strings, remember that set operations are case-sensitive. This means 'Python' and 'python' are considered two distinct elements, so an intersection might miss matches you'd consider identical. The standard fix is to normalize your data first by creating temporary, lowercase versions of your lists before finding the intersection.
Because sets are inherently unordered, converting your lists to sets and back again will lose the original sequence of the elements. The final list of common items won't necessarily reflect the order in which they appeared in your original lists. If you need to preserve the order from one of the original lists, a list comprehension is a better choice.
Handling unhashable types in set() operations
You'll run into a TypeError: unhashable type: 'list' when your lists contain other lists. This error occurs because sets require immutable elements, but lists themselves are mutable. The following code demonstrates what happens when you try this operation.
lists1 = [[1, 2], [3, 4]]
lists2 = [[3, 4], [5, 6]]
common = set(lists1) & set(lists2)
print(common)
This code fails because it tries to add lists like [1, 2] directly into a set. Since lists are mutable, they can't be hashed. The corrected code below shows how to make them compatible with set operations.
lists1 = [[1, 2], [3, 4]]
lists2 = [[3, 4], [5, 6]]
lists1_tuples = [tuple(item) for item in lists1]
lists2_tuples = [tuple(item) for item in lists2]
common = set(lists1_tuples) & set(lists2_tuples)
print(common)
The solution is to convert each inner list into a tuple. Because tuples are immutable, they can be hashed and added to a set, which is something you can't do with lists. The corrected code uses a list comprehension to transform each list with tuple(), making the set intersection work. Keep this trick in mind whenever you're comparing nested lists or other mutable objects that need to be added to a set.
Case sensitivity issues when intersecting string lists
When intersecting lists of strings, you might get unexpected results because set operations are case-sensitive. Python treats strings with different capitalization, like "Apple" and "apple", as completely separate items, which can lead to an empty intersection. The code below shows this in action.
fruits1 = ["Apple", "Banana", "Orange"]
fruits2 = ["apple", "orange", "grape"]
common_fruits = set(fruits1) & set(fruits2)
print(common_fruits) # Returns empty set
Because the & operator is case-sensitive, it treats "Apple" and "apple" as different strings, which is why the intersection is empty. The corrected code below shows how to get the expected result.
fruits1 = ["Apple", "Banana", "Orange"]
fruits2 = ["apple", "orange", "grape"]
common_fruits = set(word.lower() for word in fruits1) & set(word.lower() for word in fruits2)
print(common_fruits)
The fix is to normalize the strings by converting them to a consistent case before the intersection. The corrected code uses a generator expression like set(word.lower() for word in fruits1) to create temporary lowercase sets on the fly.
This ensures that strings like "Apple" and "apple" are treated as the same element, giving you the correct intersection. Always consider normalizing your string data when case differences don't matter for your comparison.
Preserving order in set intersection results
Set operations are incredibly fast, but this speed comes at the cost of order. Since sets are unordered collections, converting your lists to a set and back again means the final intersection won't necessarily maintain the original sequence. The following code shows this in action.
ordered_list1 = [1, 2, 3, 4, 5]
ordered_list2 = [4, 5, 6, 7, 8]
intersection = list(set(ordered_list1) & set(ordered_list2))
print(intersection) # Order might be [5, 4]
By converting the lists to sets with set(), the code loses the original order of the elements. The final list is then created from this unordered intersection, so its sequence is unpredictable. The corrected code below shows how to fix this.
ordered_list1 = [1, 2, 3, 4, 5]
ordered_list2 = [4, 5, 6, 7, 8]
intersection = list(set(ordered_list1) & set(ordered_list2))
intersection.sort() # Restore original order
print(intersection) # Will be [4, 5]
The solution is to call the sort() method on the final list. This reorders the elements into a predictable, ascending sequence, guaranteeing your output is consistent every time. While this doesn't restore the original order from either input list, it's crucial when the sequence of results matters. Use this approach to get a reliable order after leveraging the speed of set operations for the intersection itself.
Real-world applications
Beyond the code, these intersection techniques power common features in applications you use every day, from social media to data analysis.
Finding common interests between users
Social media platforms often use set intersections to connect users by identifying shared hobbies and preferences.
user1_interests = ["movies", "books", "hiking", "cooking", "photography"]
user2_interests = ["gaming", "hiking", "photography", "travel", "music"]
common_interests = list(set(user1_interests) & set(user2_interests))
print(f"Common interests: {common_interests}")
This snippet efficiently finds common items between two lists of user interests. It starts by converting both user1_interests and user2_interests into sets.
- Using the
&operator, it performs an intersection to isolate only the elements present in both original lists. - The result, a set containing 'hiking' and 'photography', is then converted back into a list with
list()before being printed.
This approach is a concise way to compare two collections and extract their shared values.
Analyzing social network connections with set()
Python's set() provides a powerful and intuitive way to analyze social network data, from finding mutual friends to identifying every unique person in the network.
network = {
"Alice": {"Bob", "Charlie", "Diana", "Eve"},
"Bob": {"Alice", "Charlie", "Frank", "Grace"},
"Charlie": {"Alice", "Bob", "Diana", "Helen"}
}
mutual_friends = network["Alice"] & network["Bob"]
print(f"Mutual friends of Alice and Bob: {mutual_friends}")
all_connections = set().union(*network.values())
print(f"All people in the network: {all_connections}")
This code models a social network with a dictionary where each person's friends are stored in a set, making membership checks and comparisons highly efficient.
- To find mutual friends, it uses the intersection operator (
&) on the friend sets for"Alice"and"Bob", which isolates the names present in both. - To identify every unique person, it uses
set.union()with the splat operator (*). This unpacks all the friend sets from the dictionary's values and merges them into a single set, automatically handling duplicates.
Get started with Replit
Put your new skills to work and build a real tool. Just tell Replit Agent what you need: "a script to find common IDs in two CSV files" or "a utility that finds mutual followers between two lists."
It handles writing the code, testing for errors, and deploying your app. You just supply the idea. Start building with Replit.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.



.png)