The A-Z of Python’s itertools.product() Method

itertools.product() is a part of a python module itertools; a collection of tools used to handle iterators. Together all these tools form iterator algebra. Itertools will make your code stand out. Above all, it will make it more pythonic.

One would question the need for itertools. They are faster and much more memory efficient.

The itertools are of the following types:

  • Infinite iterators
  • Terminating iterators
  • Combinatoric iterators

Although the itertools library contains many valuable functions, we will discuss the itertools.product() method of combinatoric iterators, you can check out the other methods from here.

Decoding the itertools.product() Method

This method of itertools determines the cartesian product of two sets(here list).

Cartesion product

The collection of all ordered pairs of two given sets (here list) such that the first elements of the pairs are chosen from one set and the second element from the other set.

A × B = {(a, b) : a ∈ A and b ∈ B}

Import

import itertools 
# or can directly import 
from itertools import product

Syntax & Parameters

Syntax:

itertools.product(*iterables, repeat)

Parameters:

  • Iterables: Iterable are objects which generate an iterator. For instance, common python iterable are list, tuple, string, dictionaries.
  • Repeat: It is an optional parameter and accepts whole numbers as value. When used it returns the cartesion product of the iterable with itself for the number of times specified in repeat parameter.

Return type

It returns an iterator which can be iterated over to get individual values one at a time.

return type itertools.product()
The return type of itertools.product()

Time complexity

The time complexity for itertools.product() is O(m*n), where m and n are the sizes of the two lists.

The itertools.product() Hackerrank problem

Problem Statement

The above problem requires you to find the cartesian product of two lists provided separately through input. Given below is a simple solution using the product() method.

Let’s briefly discuss the steps involved:

  • the map functions takes in the inputs of the list A and B (read question provided in the link above) and store them into list1 and list2 respectively.
  • then we take the cartesian product of the list1 and list2 using the product() method of itertools.
  • at last we iterate over the cart_product to print out the tuples of cartesian product.
from itertools import product

list1 = list(map(int,input().split()))
list2 = list(map(int,input().split()))

cart_product = product(list1,list2)
for item in cart_product:
    print(item,end=" ")
hackerrank itertools.product()
The output of the Hackerrank problem

itertools.product() to list

One can very quickly convert iterator by using the list() function.

import iterools

list_A = [1,2,3]
list_B = [4,5,6]

iter_to_list = list(itertools.product.(list_A, list_B))
print(iter_to_list)
converting itertools.product() returning iterator to list example 1
converting iterator to list using list() function

Another unique way to replicate the above example is to use the * operator to unpack the values:

ite = itertools.product.(list_A, list_B)
iter_to_list = [*ite]
print(iter_to_list)
converting itertools.product() returning iterator to list example 2
converting iterator to list using * operator

Replacing for loop by using itertools

In addition, the product() method can be used instead of for loop; it is concise and much faster.

Let’s briefly discuss the code below:

  • We have imported the time library, to measure the speed of executions of itertools product() method and for loop.
  • In the first iteration of the for loop i = 1, j = 4 and k = 7, it exhausts the list3 for values of k 8 & 9. Then it sets j = 5 and repeats the steps.
  • In the second iteration of the for loop i = 2, j = 4 and k = 7, it exhausts the list3 for values of k 8 & 9. Then it sets j = 5 and repeats the steps. This is similarly repeated for i = 3.
  • s1, s2 denote the starting time of itertools product() method and for loop executions repectively, similarly e1 , e2 denote end times. e1 – s1 and e2 – s2 give the running times of product() method and for loop.
import time
import itertools

list1 = [1,2,3]
list2 = [4,5,6]
list3 = [7,8,9]

s1 = time.time()
iter_list = itertools.product(list1,list2,list3)
e1 = time.time()

print("Output for itertools.product()")
print(list(iter_list))

list_new = []
s2 = time.time()
for i in list1:
	for j in list2:
		for k in list3:
			list_new.append((i,j,k))
e2 = time.time()

print("Output for FOR loop")
print(list_new)

print(f"Time for itertools.product():{e1-s1}")
print(f"Time for regular for loop:{e2-s2}")
Time difference between itertools method product()  and for loop
Time difference between itertools method product() and for loop

Python itertools product() with conditions

We can add conditions to the product() method with the filter function. For instance, given below example filters only the tuples starting with an even number.

Let’s briefly discuss the code below:

  • Python’s filter function takes in a ‘function’ and an ‘iterable’ , it filters out the results according to the conditions of the function.
  • product() method has repeat set to 4, what it does is; it return all the ways to arrange the vals numbers where repeats are allowed.
  • Then lambda function filters out the tuples starting with an even number.
from itertools import product

vals = [1,2,3,4]
values = filter(lambda vals:int(vals[0]) % 2 == 0,product(vals,repeat=4))
print(list(values))
itertools.product() with condition
Itertools product implementation with a condition

Generating dataframe using itertools.product()

You can generate dataframes using the method and apply a function to generate column/s.

Let’s briefly discuss the code below:

  • In order to generate a dataframe from itertools product() method, we have specified a lambda function.
  • Here lambda function ‘func’ takes the ‘i’ and ‘j’ values of the cartesian product of lists a & b and adds them.
  • Values generated through ‘func’ results in third column of the dataframe.
  • Similarly, you can create multiple columns for your dataframe.
from pprint import pprint

a = [1,2,3]
b = [4,5,6]
func = lambda i, j: i+j
result = [(i, j, func(i,j)) for i, j in itertools.product(a, b)]
pprint(result)
dataframe using itertools product() method
Generated dataframe

FAQs on Python itertools Products

zip() vs itertools.product()

One might find a couple zip and product() methods of itertools together as both return iterators however they are miles apart. The zip function couples respective elements of lists while the product() follows the cartesian product rule.
list_A = [1,2,3]
list_B = [4,5,6]
print(zip(list_A,list_B)
print(list(itertools.product(list_A,list_B))


zip vs itertools.product()

itertools product() method vs for loop

itertools product() method can be used instead of for loop. It is much faster has minimum code clutter. Since itertools product() method gives an iterator which only returns value one by one; only if called upon.

Conclusion

In conclusion, itertools.product() makes our code efficient, concise, and pythonic. Although we only discussed the product() method in this blog, many other methods will make your code look cleaner and run faster.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments