Skip to content
Crayon CS

Make it comfy

Lesson style

Quick mode shows the key picture, a summary and the practice. Good for a refresher.

Theme
Font

Both fonts are designed to be easy to read. Some readers with dyslexia prefer Lexend.

Text size
Spacing
Animations

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

The story

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.

Play with it

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

  1. 1grid = [[1, 2, 3],
  2. 2 [4, 5, 6]]
  3. 3total = 0
  4. 4for r in range(len(grid)):
  5. 5 for c in range(len(grid[r])):
  6. 6 total += grid[r][c]
  7. 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].

Name it

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.
  • ⚠️ Making an empty grid: [[0] * 3] * 2 creates two aliases of the same row (remember lesson 14!). Use a comprehension instead: [[0] * 3 for _ in range(2)].
Build it

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.

Challenge

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.

Remember 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?