A list comprehension can contain another list comprehension. The inner one builds each row, and the outer one collects the rows into a list of lists, often called a matrix.
The program
python
table = [[row * col for col in range(1, 4)] for row in range(1, 4)] for r in table: print(r)
output
[1, 2, 3] [2, 4, 6] [3, 6, 9]
How it works
- The outer comprehension runs once for each
row(1, 2, 3). - For each
row, the inner comprehension[row * col for col in range(1, 4)]builds one list of three numbers. - The result is a list of three lists.
table[1][2]is row 2, column 3, which is 6.
The same table with normal loops:
python
table = [] for row in range(1, 4): new_row = [] for col in range(1, 4): new_row.append(row * col) table.append(new_row) print(table)
output
[[1, 2, 3], [2, 4, 6], [3, 6, 9]]
Flatten and transpose
There are two different shapes of nested comprehension, and they are easy to mix up.
python
matrix = [[1, 2, 3], [4, 5, 6]] # Two for clauses in one comprehension: one flat list flat = [x for row in matrix for x in row] print(flat) # A comprehension inside a comprehension: a new list of lists transposed = [[row[i] for row in matrix] for i in range(3)] print(transposed)
output
[1, 2, 3, 4, 5, 6] [[1, 4], [2, 5], [3, 6]]
- In
flat, theforclauses are in the same order as in normal nested loops: firstfor row in matrix, thenfor x in row. - In
transposed, the inner comprehension takes itemifrom every row, so each column becomes a row.
If a comprehension needs more than two for clauses, or is hard to read on one line, normal loops are usually the clearer choice.