Introduction
A list can hold other lists. That gives you tables, grids, game boards and matrices: a list of rows, where each row is a list of values.
Game boards, spreadsheets, images and timetables are all tables. Python has no special table type, because a list of lists does the job, and it follows the same rules you already know.
How it works
A game board
board = [["."] * 3 for _ in range(3)]
board[1][1] = "X"
board[0][2] = "O"
for row in board:
print(" ".join(row))A comprehension builds three separate rows. Setting one cell changes only that row, and " ".join(row) prints each row as text.
The copying trap
bad = [[0] * 2] * 3
bad[0][0] = 5
print(bad)
good = [[0] * 2 for _ in range(3)]
good[0][0] = 5
print(good)[[0] * 2] * 3 does not make three rows: it makes three references to the same row. The objects panel shows three arrows pointing to one inner list, so changing bad[0][0] changes every row. The comprehension version creates a new inner list each time, which is what you almost always want.
Syntax
grid = [[1, 2, 3], [4, 5, 6]]
grid[1][2] # row 1, column 2
for row in grid:
print(sum(row))
empty = [[0] * 3 for _ in range(2)]
Example
grid = [[1, 2, 3], [4, 5, 6]]
print(grid[1][2])
grid[0][0] = 9
for row in grid:
print(sum(row))grid[1][2] means "row 1, then position 2 in that row", which is 6. In the objects panel, grid points to an outer list whose two cells each point to an inner list. After grid[0][0] = 9 the first row is [9, 2, 3], so the row sums are 14 and 15.
Line by line
gridis a list holding two lists.grid[1][2]goes to row 1 and then to position 2 in that row, which is 6.grid[0][0] = 9changes one cell of the first row.for row in grid:gives one inner list on each pass.sum(row)adds up that row, giving 14 and then 15.
Expected result
6
14
15
In the real world
An image is a grid of pixels, and a chess board is a grid of squares. Numerical libraries such as NumPy store grids far more efficiently, but they use the same row-and-column thinking.
Common mistakes
[[0] * n] * mfor a grid. Use[[0] * n for _ in range(m)].- Mixing up the order:
grid[row][col], notgrid[col][row]. - Copying a grid with
grid.copy(): it copies the outer list only; the rows are still shared.
Best practices
- Always build grids with a comprehension.
- Decide once whether you write row first, and stay with it.
- Use
for row in gridwhen you do not need the positions.
Summary
A list of lists makes a table, and grid[row][col] reaches one cell. Multiplying a list of lists repeats references to the same row, so build grids with a comprehension.
Practice
Build a 3 × 3 multiplication table as a list of lists, then print the sum of its diagonal (grid[i][i]).
Quick check
Key takeaways
- grid[row][col] reads one cell.
- [[0] * n for _ in range(m)] makes separate rows.
- [[0] * n] * m repeats a reference to one row.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.