In a Python list comprehension, you can use any kind of expression you want at the beginning, including another list comprehension. This allows you to create a new list by iterating over multiple iterable objects in a nested fashion.
Syntax
The first part of a list comprehension (i.e. before the for
loop) can be any valid Python expression, even another list comprehension. This allows you to create more complex lists by nesting one or more list comprehensions inside each other.
The basic syntax for a nested list comprehension is:
new_list = [[expression for item_1 in iterable_1] for item_2 in iterable_2] | | inner loop outer loop
This is equivalent to the following:
new_list = [] # outer loop for item_2 in iterable_2: inner_list = [] # inner loop for item_1 in iterable_1: inner_list.append(expression) new_list.append(inner_list)
The order of execution of the for
clauses in a list comprehension is always from left-to-right, with the outer loop executing first, and then the inner loop executing for each iteration of the outer loop.
The decision to wrap the inner list comprehension in square brackets ([]
) depends on the desired shape of the resulting data structure. If the desired result is a single list, then there's no need for brackets, but if the desired result is a 2D list or a nested list, then brackets are necessary. This means that the following syntax is also valid, which would result in a flat list:
new_list = [expression for item_1 in iterable_1 for item_2 in iterable_2] | | outer loop inner loop
This is equivalent to the following:
new_list = [] # outer loop for item_1 in iterable_1: # inner loop for item_2 in iterable_2: new_list.append(expression)
It is, of course, possible to have multiple nested for
clauses or list comprehensions in the single list comprehension, however, it might affect readability. Therefore, in such cases, it might be better to use a for
loop instead.
Examples
For example, the following list comprehension has a nested list comprehension:
matrix = [[i*j for j in range(3)] for i in range(3)] print(matrix) # [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
In this example, the inner loop has square brackets and generates a list of 3 elements for each iteration of the outer loop. The resulting matrix is a 2D list with 3 rows and 3 columns. This is equivalent to the following:
matrix = [] for i in range(3): row = [] for j in range(3): row.append(i * j) matrix.append(row) print(matrix) # [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
Compare the examples above to the following, where using multiple for
clauses (instead of nested list comprehensions) produces a flat list:
flat_list = [i*j for i in range(3) for j in range(3)] print(flat_list) # [0, 0, 0, 0, 1, 2, 0, 2, 4]
In this example, the first loop does not have any square brackets and generates a single element for each iteration of the outer loop, resulting in a 1D (or flat) list with 9 elements. This is equivalent to the following:
flat_list = [] for i in range(3): for j in range(3): flat_list.append(i*j) print(flat_list) # [0, 0, 0, 0, 1, 2, 0, 2, 4]
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.