5 Best Ways to Find Common Elements in Three Lists in Python

πŸ’‘ Problem Formulation: You’re faced with the task of finding the intersection of three lists in Python – that is, you need to identify which elements are common across all three lists. For instance, given list1 = [1,2,3], list2 = [2,3,4], and list3 = [3,4,5], the desired output is [3], as it’s the only element present in all three lists.

Method 1: Using Set Intersection

This method involves converting lists to sets and then using the set intersection method to find the common elements. The set.intersection function is specifically designed to find common elements among sets, making it perfect for this task.

β™₯️ Info: Are you AI curious but you still have to create real impactful projects? Join our official AI builder club on Skool (only $5): SHIP! - One Project Per Month

Here’s an example:

list1 = [1, 2, 3]
list2 = [2, 3, 4]
list3 = [3, 4, 5]

common_elements = list(set(list1).intersection(set(list2), set(list3)))
print(common_elements)

Output: [3]

This snippet converts each list to a set and then computes the intersection, converting the result back to a list to get the common elements. It’s efficient and easy to understand, but it only works with hashable (i.e., immutable) elements.

Method 2: Using List Comprehension

We can use list comprehensions to create a new list containing only elements that are present in all three lists. This is a more explicit approach and easy to read, but it can be less efficient than set operations for large lists.

Here’s an example:

list1 = [1, 2, 3]
list2 = [2, 3, 4]
list3 = [3, 4, 5]

common_elements = [element for element in list1 if element in list2 and element in list3]
print(common_elements)

Output: [3]

The list comprehension iterates through the first list and includes only those elements that are also found in both of the other two lists. Although it’s simple, it’s not the most efficient method for large lists due to the O(n^2) complexity.

Method 3: Using functools and reduce

The functools.reduce() function can apply a particular function cumulatively to the items of an iterable. By applying the intersection operator through reduce(), we seamlessly find common elements across multiple lists.

Here’s an example:

from functools import reduce

list1 = [1, 2, 3]
list2 = [2, 3, 4]
list3 = [3, 4, 5]

common_elements = reduce(lambda x, y: x & y, map(set, [list1, list2, list3]))
print(list(common_elements))

Output: [3]

This approach maps each list into a set and then reduces them by intersecting each set cumulatively. It’s a functional programming style of solution and works very well with a varying number of lists, but it might be less readable for those not familiar with functional paradigms.

Method 4: Using the Counter Object from the Collections Module

The Collections.Counter class can find common elements by counting occurrences and then identifying counts that equal the number of lists. It’s suitable for unhashable types and gives additional information like the number of occurrences.

Here’s an example:

from collections import Counter

list1 = [1, 2, 3]
list2 = [2, 3, 4]
list3 = [3, 4, 5]

aggregate_counter = Counter(list1) & Counter(list2) & Counter(list3)
common_elements = list(aggregate_counter.elements())
print(common_elements)

Output: [3]

Each list is converted to a Counter object, and the intersection of these counters gives us the common elements. This method is particularly useful when the lists may contain duplicates, and you want to ensure the common elements are present in the same number in each list.

Bonus One-Liner Method 5: Using a Nested Filter and All

A compact one-liner can be crafted using filter and the all function to check for membership across all lists. It’s a succinct, expressive solution but can be harder to read and less efficient than set-based approaches.

Here’s an example:

list1 = [1, 2, 3]
list2 = [2, 3, 4]
list3 = [3, 4, 5]

common_elements = list(filter(lambda x: all(x in lst for lst in [list2, list3]), list1))
print(common_elements)

Output: [3]

This one-liner filters list1 by checking if every element is also in both list2 and list3. It showcases the power of Python’s functional features but may be less performant due to repeated iteration over all lists.

Summary/Discussion

  • Method 1: Set Intersection. High performance. Does not preserve order and requires hashable elements.
  • Method 2: List Comprehension. Explicit and easy to read. Potentially inefficient for large lists.
  • Method 3: functools and reduce. Flexible and concise. Less intuitive for those not familiar with functional programming.
  • Method 4: Counter Object. Great for duplicate elements and unhashable types. Slightly more complex and slower for simple use-cases.
  • Method 5: Nested Filter and All. Elegant one-liner. Less efficient and can be trickier to comprehend.