Show how to build and traverse a nested Python list, including flattening it.
A nested list is a list whose items are themselves lists. The clearest way to build one is with a list comprehension, and the clearest way to read one is with a loop that goes row by row. The earlier questions in this topic covered ordinary lists, so this answer builds directly on that foundation and adds the idea of a list inside a list.
matrix = [
[1, 2, 3],
[4, 5, 6],
]
# Build a table from scratch, one row at a time.
table = []
for row in range(2):
new_row = []
for col in range(3):
new_row.append(row * 3 + col)
table.append(new_row)
print(table) # [[0, 1, 2], [3, 4, 5]]
# Read the table row by row.
for row in matrix:
print(row)
# Flatten the table into one list.
flat = []
for row in matrix:
for value in row:
flat.append(value)
print(flat) # [1, 2, 3, 4, 5, 6]
The flattening loop has two loops inside it, and the order matters. The outer loop walks through the rows, and the inner loop walks through the values of one row. That is why the values come out row by row. If you swap the two loops, the program tries to walk through the individual numbers and it fails with an error.
Reading one value from a nested list uses two sets of square brackets. The expression matrix[0][1] means the second value of the first row. You can also unpack a whole row at once, like first, second, third = row, and that works as long as every row has the same number of values. If one row is shorter, Python raises a ValueError and tells you that the values did not match up.
Two things are worth remembering when you build nested structures. The first one is that each inner list must be built separately. Writing [[]] * 3 creates three references to the same inner list, so changing one of them changes all three. The second one is that a plain copy of the outer list still shares the inner objects, so a change inside one row is visible from every place that row is used.