How to get the cartesian product of a series of lists?

How To Get The Cartesian Product Of A Series Of Lists

In this tutorial, I am going to demonstrate the different methods that you can use to get the cartesian product of a series of lists. You will learn 3 methods to find the cartesian product of a series of lists.
Let us start by getting a recap of Python lists.


What are Python lists?

A list in Python is a data structure that stores data elements in an ordered sequence. It is much similar to arrays in other programming languages like C++, Java, etc. The data items stored inside a list can of different types (e.g. integers, strings, etc.).
The elements inside a list can be directly accessed using their indexes. Python lists are mutable, which implies that you can add, remove and modify the elements after the list is created.

Lists can be created using square brackets [] in Python. Here are some examples:

colours =  ['red', 'green', 'blue', 'pink']

my_list = [4, 'flower', 87, 25.36]

Now that you have recalled what lists are, let me explain you about cartesian product.

What is cartesian product?

In mathematics and computer science, the Cartesian product of two sets A and B is a set of all possible ordered pairs (a, b), where a is an element of A and b is an element of B. The Cartesian product is denoted by A × B.

For example, if A = {1, 2} and B = {3, 4}, then their Cartesian product A × B is:

A × B = { (1, 3), (1, 4), (2, 3), (2, 4) }

Note that since cartesian product is ordered, A x B is not the same as B x A.

The Cartesian product B x A is:

B × A = { (3, 1), (3, 2), (4, 1), (4, 2) }

The Cartesian product can also be extended to more than two sets. For example, if A = {1, 2}, B = {3, 4}, and C = {5, 6}, then their Cartesian product A × B × C is:

A × B × C = { (1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6) }

The cardinality of the cartesian product of two sets A and B is the total number of ordered pairs in A x B.

Also Read: How to Divide Each Element in a List in Python?


Methods to find the cartesian product of a series of lists

In Python, there are 3 methods that you use to find the cartesian product of a series of lists. Let us see all of them one-by-one.

Method 1: Using List Comprehension

List comprehension is a way of writing shorter or concise syntax for creating a new list based on the existing list. You can use list comprehension to find the cartesian product of lists.

Here is an example of finding the cartesian product of two lists using list comprehension.

list1 = [2, 5]
list2 = ['car', 'cycle']

# list1 x list2
cartesian_product = [(a, b) for a in list1 for b in list2]

print(cartesian_product)

Output:

[(2, 'car'), (2, 'cycle'), (5, 'car'), (5, 'cycle')]

The above example consisted of two independent lists, but you can pass any iterable collection or a combination of iterables as well. Similarly, you can find the cartesian product of a series of lists as shown below:

lists = [
    [10, 30], 
    ['rose', 'tulip'],
    [1.5, 3.6]
]

# lists[0] x lists[1] x lists[2]
cartesian_product = [(a, b, c) for a in lists[0] for b in lists[1] for c in lists[2]]

print(cartesian_product)

This is the same as writing 3 nested for loops like this:

cartesian_product = []

# lists[0] x lists[1] x lists[2]
for a in lists[0]:
    for b in lists[1]:
        for c in lists[2]:
            cartesian_product.append((a, b, c))
            
print(cartesian_product)

Both the above codes will the same output which is:

[(10, 'rose', 1.5), (10, 'rose', 3.6), (10, 'tulip', 1.5), (10, 'tulip', 3.6), (30, 'rose', 1.5), (30, 'rose', 3.6), (30, 'tulip', 1.5), (30, 'tulip', 3.6)]

Method 2: Using recursion

You can also find the cartesian product of a series of lists using recursion.

def cartesian_product(lists):
    if not lists:
        yield ()
    else:
        for a in lists[0]:
            for num in cartesian_product(lists[1:]):
                yield (a,) + num
                
                
list1 = [3, 67]
list2 = [10, 4]
ans = list(cartesian_product([list1, list2]))
print(ans)

Output:

[(3, 10), (3, 4), (67, 10), (67, 4)]

Recommended Read: Python yield


Method 3: Using itertools.product()

The itertools module is a standard library module in Python that provides a collection of functions for working with iterators and iterable objects. The functions in the itertools module can be used to generate iterators for common tasks such as iterating over all possible combinations and permutations of a set of items, repeating items, and grouping items.

One of the functions in this module is product().

product(*iterables, repeat=1) – This function generates the Cartesian product of the input iterables, with the optional repeat argument specifying the number of times each input iterable should be repeated.

Here is how you can use the itertools.product() function to find the cartesian product of a series of lists.

from itertools import product

list1 = [2, 'car']
list2 = [10, 4]

ans = list(product(list1, list2))

print(ans)

Output:

[(2, 10), (2, 4), ('car', 10), ('car', 4)]

You can also directly pass a series of lists to the function like this:

from itertools import product

lists = [[3, 12], ['hello', 'world'], [4.2, 8.4]]

for i in product([3, 12], ['hello', 'world'], [4.2, 8.4]):
    print(i)

Output:

(3, 'hello', 4.2)
(3, 'hello', 8.4)
(3, 'world', 4.2)
(3, 'world', 8.4)
(12, 'hello', 4.2)
(12, 'hello', 8.4)
(12, 'world', 4.2)
(12, 'world', 8.4)

Conclusion

In this tutorial, you learnt how to find the cartesian product of a series of lists using Python. You saw 3 different methods to achieve the result. The methods were as follows:

Get the cartesian product of a series of lists using the following 3 methods.

  • Using List Comprehension
  • Using Recursion
  • Using itertools.product() function

Reference