Nested Lists and Matrices
15 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)A list containing other lists is a nested list, ideal for representing matrices, game boards, and tables. Beware of Python's reference multiplication behavior.
2D lists and coordinate access
Nested list is a list whose items are lists. It models a table: the outer list holds the rows, each row is an inner list, and matrix[row][col] reads one cell.
Access items using row and column indices: matrix[row][col].
grid = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]print(grid[1][2])Example 1 · Adding up every cell
matrix = [ [10, 20], [30, 40]]total_sum = 0for row in matrix: for val in row: total_sum += val
print(f"Matrix sum: {total_sum}")Matrix sum: 100
What this code does
- The outer loop takes one row at a time. The inner loop takes each value in that row.
- All 4 cells are added: 10 + 20 + 30 + 40 = 100.
grid[1] accesses the second row [4, 5, 6], and [2] accesses the third column element 6.
The [[0]*N]*N trap
Writing [[0] * 3] * 3 creates three references to the exact same row list in memory.
bad_grid = [[0] * 3] * 3bad_grid[0][0] = 9print(bad_grid)Example 2 · Shared rows
seats = [["free"] * 3] * 2seats[0][1] = "booked"print(seats)[['free', 'booked', 'free'], ['free', 'booked', 'free']]
What this code does
* 2repeats a reference to the same row, it does not build a second row.- So the change made through
seats[0]also shows inseats[1].
Modifying bad_grid[0][0] changes the first element in all three rows ([[9, 0, 0], [9, 0, 0], [9, 0, 0]]) because all three rows point to the same memory object!
Creating grids properly with comprehensions
Always use a list comprehension to create distinct, independent row lists.
good_grid = [[0] * 3 for _ in range(3)]good_grid[0][0] = 9print(good_grid)Example 3 · Row totals with a comprehension
sales = [[120, 80, 100], [90, 60, 110]]row_totals = [sum(row) for row in sales]first_column = [row[0] for row in sales]print(row_totals)print(first_column)[300, 260] [120, 90]
What this code does
- Looping over
salesgives one row at a time, sosum(row)adds that row. row[0]picks the first cell of every row, which is the first column.
Each iteration of the comprehension instantiates a fresh row list in memory, modifying only good_grid[0][0].
Copying a nested list
Shallow copy is a new outer list whose items are the same inner lists as before. Changing a cell through the copy also changes the original. copy.deepcopy() copies the inner lists too.
A copy of a nested list can still share its rows. Use copy.deepcopy() when the copy must be fully independent.
import copy
grid = [[1, 2], [3, 4]]shallow = grid.copy()deep = copy.deepcopy(grid)grid[0][0] = 99print(shallow)print(deep)Example 4 · A table copy that stays independent
table = [[1, 2], [3, 4]]safe = [row[:] for row in table]table[0][0] = 50print(table)print(safe)[[50, 2], [3, 4]] [[1, 2], [3, 4]]
What this code does
row[:]copies each row, sosafehas its own rows.- The change to
tabledoes not reachsafe.
shallow has its own outer list but shares the rows, so it shows 99. deep copied the rows too, so it keeps the old value.
Next step
Check your understanding
9 quick questions