Lesson 16 of 26 · about 18 min
Grids and images
A list of lists makes a grid. A digital image is exactly that, a grid of pixels, so with two nested loops you can write your own photo filters.
🧭 What you need first: Tuples and list comprehensions , Pictures as numbers
Think of a cinema seating chart: rows A, B, C…, and seats 1, 2, 3… in each row. To name a seat, you need two pieces of information: the row and the seat number.
A Python list can hold anything, including other lists. Put each row’s seats in a list, then put the rows in a list, and you have a grid. seats[2][5] means “row 2, seat 5.”
Here’s the exciting part: every photo on your phone is a grid like this, just millions of cells big. Each cell, or pixel, holds three numbers for red, green and blue (remember F01). A photo filter is just a loop that visits every pixel and changes its numbers.
Another way: a spreadsheet
A spreadsheet has rows and columns. Pick a row, then a column, and you’ve found a cell. A 2D list is a spreadsheet in Python: a list of rows, each row a list of cells.
Another way: a chessboard
Each square has a row and a column. To check every square, you go row by row, and within each row square by square. That’s two loops, one inside the other.
A tiny grid, step by step
Watch the outer loop pick a row while the inner loop walks across it.
Watch the code run, one step at a time
- 1grid = [[1, 2, 3],
- 2 [4, 5, 6]]
- 3total = 0
- 4for r in range(len(grid)):
- 5 for c in range(len(grid[r])):
- 6 total += grid[r][c]
- 7print("rows:", len(grid), "cols:", len(grid[0]), "total:", total)
➜ yellow = the line about to run · ✓ = the line that just ran
Now a real picture. Run it, then try "sunset" or "smiley", and change one pixel to bright blue: img[5][5] = [0, 0, 255].
The real words
- A 2D list is a list whose items are lists.
grid[r]is a whole row;grid[r][c]is one cell. - Row first, then column. It’s like reading: top to bottom, then left to right.
- Number of rows:
len(grid). Number of columns:len(grid[0]). - Visiting every cell needs nested loops: the inner loop runs completely for each round of the outer loop.
for r in range(len(grid)):
for c in range(len(grid[r])):
# do something with grid[r][c]- In an image, each cell is a pixel
[red, green, blue]. Since each pixel is a little list, you can change it in place:img[r][c] = [255, 0, 0]. - Common filters:
- Invert: each channel becomes
255 - value. - Grayscale: set all three channels to the average of the three.
- Mirror: swap pixels from the left and right sides of each row.
- Invert: each channel becomes
- ⚠️ Making an empty grid:
[[0] * 3] * 2creates two aliases of the same row (remember lesson 14!). Use a comprehension instead:[[0] * 3 for _ in range(2)].
Write your own photo filters
Turn the flower into a negative (invert every channel: 255 - value), then show it. Use nested loops to change img in place.
Grayscale and a mirror
Make the sunset grayscale (each channel = the average of the three, as a whole number), then mirror it left-to-right. Show it.
grid = [[1, 2, 3], [4, 5, 6]]. What is grid[1][0]?
Got it?
Finish the lesson to color it in on your map and collect its concept cards.
Did this lesson click?