5 Best Ways to Find Cartesian Product of Two Lists in Python

πŸ’‘ Problem Formulation: This article aims to guide Python programmers on various approaches to find the Cartesian product of two lists. The Cartesian product is the set of all possible pairs (a, b), where ‘a’ is from the first list and ‘b’ is from the second list. For example, given two lists: [1, 2] and ['a', 'b'], the desired output is [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')].

Method 1: Using Itertools’ product Function

The product() function from Python’s itertools library is a direct way to compute the Cartesian product of multiple lists. It returns a generator producing all possible pairs in the form of tuples, thus being memory-efficient for large lists.

Here’s an example:

import itertools

list1 = [1, 2]
list2 = ['a', 'b']

cartesian_product = list(itertools.product(list1, list2))
print(cartesian_product)

Output: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

In this snippet, we first import the itertools module and then use the product() function, passing the two lists as arguments. The result is cast to a list from a generator and printed, showcasing the desired Cartesian product.

Method 2: Nested For Loops

Nested for loops are a simple and straightforward way to find the Cartesian product without needing any external libraries. This method executes a for loop within another for loop to consider all possible pairings.

Here’s an example:

list1 = [1, 2]
list2 = ['a', 'b']

cartesian_product = [(x, y) for x in list1 for y in list2]
print(cartesian_product)

Output: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

Here we utilize a list comprehension to perform the nested iteration in a more concise manner. The outer loop iterates over the first list, and the inner loop iterates over the second list, creating tuples with all possible combinations.

Method 3: Using a Helper Function

Crafting a custom helper function to compute the Cartesian product provides flexibility and reuse potential. This method encapsulates the logic in a function that can be called with any two lists to get their Cartesian product.

Here’s an example:

def cartesian_product(list1, list2):
    result = []
    for x in list1:
        for y in list2:
            result.append((x, y))
    return result

list1 = [1, 2]
list2 = ['a', 'b']
print(cartesian_product(list1, list2))

Output: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

The custom function cartesian_product() creates an empty list and populates it with tuples representing the pairs from the input lists. This tailored solution is called with the desired lists and returns the resulting Cartesian product.

Method 4: Using the itertools’ starmap and product Functions

The combination of starmap() and product() from itertools allows mapping a function over each pair generated by the Cartesian product, which can be handy when additional operations need to be applied to the pairs.

Here’s an example:

import itertools

def pair(x, y):
    return (x, y)

list1 = [1, 2]
list2 = ['a', 'b']

cartesian_product = list(itertools.starmap(pair, itertools.product(list1, list2)))
print(cartesian_product)

Output: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

This code introduces a function pair() which is then applied to each tuple yielded by product() using starmap(). This allows additional customization in how the pairs are processed or returned.

Bonus One-Liner Method 5: Using a Lambda Function in a List Comprehension

Applying a lambda function in a list comprehension can achieve the Cartesian product in a very concise one-liner. This is most suitable for simple cases and those familiar with lambda functions and comprehensions.

Here’s an example:

list1 = [1, 2]
list2 = ['a', 'b']

cartesian_product = [(lambda x, y: (x, y))(x, y) for x in list1 for y in list2]
print(cartesian_product)

Output: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

The lambda function creates a pair and is immediately invoked within the list comprehension. The resulting list contains all possible pairs from the two input lists, thus forming the Cartesian product.

Summary/Discussion

  • Method 1: Itertools’ product Function. Ideal for its simplicity and efficiency. It handles large data sets well but requires an external library.
  • Method 2: Nested For Loops. Straightforward and doesn’t need any imports. However, it can get unwieldy with very large lists due to potential performance issues.
  • Method 3: Using a Helper Function. Offers modularity and reusability. It’s more verbose than other methods and can be overkill for simple tasks.
  • Method 4: Itertools’ starmap and product Functions. Provides advanced flexibility by allowing function mapping, but might be more complex for beginners.
  • Method 5: Lambda Function in a List Comprehension. Compact and elegant; however, it may sacrifice readability for those not accustomed to lambdas or comprehensions.