Chapter 3 · Data
Tuples, loops and grids
Step 1 of 22 · Concept
A tuple is a fixed group
In this lesson you group values in tuples, stop loops early, and build grids from lists of lists.
point = (3, 4)
- A tuple is values in round brackets: a fixed group.
point[0]is3andlen(point)is 2, as with a list. - A tuple cannot change.
point[0] = 5stops withTypeError: 'tuple' object does not support item assignment. - A tuple of one value needs a comma:
(5,).(5)is only the number 5.
Step 2 of 22 · Try it
Try it: a new point
Run it: TypeError: 'tuple' object does not support item assignment. Make a new tuple instead, as with text.
Replace line 2 with point = (5, point[1]). Then it prints (5, 4), and line 4 shows a one-value tuple beside
the number 5.
The new tuple takes 5 for item 0 and keeps the old item 1, point[1]. Then point points at it.
Step 3 of 22 · Concept
Unpack a tuple into names
x, y = point unpacks the tuple: x gets item 0, y gets item 1. There must be as many names as items.
- Swap two names in one line:
a, b = b, a. Python makes the tuple on the right first. - A function can return two values:
return lo, hireturns one tuple, and the caller unpacks it.
Step 4 of 22 · Quiz
Predict the swap
Type exactly what this program prints.
def min_max(xs):
return min(xs), max(xs)
a, b = 1, 2
a, b = b, a
print(a, b)
lo, hi = min_max([7, 2, 9])
print(lo, hi)
print(min_max([7, 2, 9]))
Step 5 of 22 · Demo
See it run
Run it and compare with your answer. Then change the last line to print(lo + hi).
Step 6 of 22 · Demo
enumerate and zip give pairs
enumerate(names, start=1) gives pairs: a number from 1, and each item. Without start=, the count starts at 0,
like an index. zip(names, scores) pairs two lists item by item.
for place, name in ... unpacks each pair into two names. Run it.
Step 7 of 22 · Exercise
Your turn: lowest and highest
Finish low_high(xs): in one loop, without min or max, find the lowest and the highest number of xs. Return
both. The program must print:
2 9
(5, 5)
Start both at the first number, xs[0]. Starting at 0 gives the wrong lowest when every number is bigger.
Loop over xs. A number below low becomes the new low; a number above high the new high. Then return low, high.
low, high = xs[0], xs[0]
Step 8 of 22 · Concept
break stops a loop, continue skips a round
| write | does |
|---|---|
break | leaves the loop at once |
continue | skips the rest of this round; the next round starts |
Both act on the loop they are in, the innermost one.
A search sets found = None before its loop. None is Python's value for "nothing" (lesson 7).
After the loop, if found is None: tells whether anything was found. Compare with None using is.
Step 9 of 22 · Quiz
Predict the search
Type exactly what this program prints.
nums = [4, 0, 7, -2, 5, -9]
found = None
for i, n in enumerate(nums):
if n == 0:
continue
if n < 0:
found = i
break
print("checked", n)
if found is None:
print("none")
else:
print("first negative at", found)
Step 10 of 22 · Demo
See it run
Run it and compare with your answer. Then change -2 and -9 to 2 and 9: the program prints none.
Step 11 of 22 · Exercise
Your turn: the first fail
Find the first score under 50 and its place, counting from 1. Print First fail:, the score, at and the place,
or No fail when no score is under 50. The program must print:
First fail: 48 at 3
Then change 48 and 30 to 58 and 60: it must print No fail.
Go through the scores with enumerate(scores, start=1), and stop at the first one under 50.
Set found = None before the loop, or the name does not exist when no score fails. In the loop: keep the place and the score, then break.
if found is None:
print("No fail")
Step 12 of 22 · Concept
A loop inside a loop
A loop can sit in another loop's block. The inner loop runs to the end in every round of the outer one.
for r in range(1, 3):
for c in range(1, 4):
print(r, c)
That makes six prints: three for r 1, then three for r 2.
Step 13 of 22 · Demo
A times table
end="" keeps print on the same line (lesson 7), and print() alone ends the row. {r * c:>4} gives each
number 4 columns (lesson 9). Run it.
Step 14 of 22 · Try it
Try it: a triangle of numbers
Row i shows the numbers from 1 to i, with no spaces. The outer loop is given: write the inner loop in place of
the comment. The program must print:
1
12
123
1234
The inner loop's stop depends on i: range(1, i + 1) ends at i. Inside it, print(j, end="").
Step 15 of 22 · Concept
A grid is a list of rows
A grid is a list of rows, and each row is a list.
grid = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
grid[1]is the row[4, 5, 6].grid[1][2]is index 2 of that row:6.len(grid)counts the rows, 3.len(grid[0])counts the cells of a row, 3.
Step 16 of 22 · Demo
Print a board
Two loops build the board, one new row per round. Two more print it, a row per line. Run it.
Step 17 of 22 · Quiz
Which grid?
[0] * 3 is [0, 0, 0]: * repeats a list as it repeats text (lesson 4). What does this program print?
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)
Step 18 of 22 · Demo
[[0] * 3] * 3 is one row, three times
* 3 repeats what the outer list holds: an arrow. So all three arrows point at one row. Build each row in a loop
instead, as the board did.
Run it and compare with your answer.
Step 19 of 22 · Exercise
Your turn: a times grid
- Build
gridwith loops: 4 rows of 4 numbers, wheregrid[r][c]is(r + 1) * (c + 1). - Print each row, each number in 3 columns.
The last line, the number of rows and of columns, is given.
The program must print:
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
4 rows, 4 columns
Build as the board did: a new empty row in each outer round, filled by the inner loop, then added to grid.
Then print with two loops, as the times table did: print(f"{x:>3}", end="") for each number, print() after each row.
row.append((r + 1) * (c + 1))
Step 20 of 22 · Check yourself
Check yourself: a winning row
- Find the first row of
boardwhose three cells are all"X", numbering the rows from 1. - Print
Row, its number andis all X, orNo row is all X.
The output must be exactly:
Row 3 is all X
This is the search of the first fail again, over the rows of the grid instead of the scores.
Step 21 of 22 · Challenge · optional
Challenge: columns too
Optional.
Build wins, a list with one True or False per column: True when the column is all "X". Then print
wins and whether any column wins, with True in wins. The program must print:
[False, True, False]
True
Column c is row[c] of every row. Loop over the column numbers, and inside over the rows.
Start each column at True, and set it to False when a cell is not "X". Append it to wins after the inner loop.
if row[c] != "X":
all_x = False
Step 22 of 22 · Recap
Recap
- A tuple such as
(3, 4)is a fixed group: it cannot change. x, y = pointunpacks a tuple;a, b = b, aswaps two names.enumeratenumbers the items,zippairs two lists.breakleaves a loop,continueskips a round; checkfound is Noneafter a search.- A grid is a list of rows,
grid[r][c].[[0] * 3] * 3is one row three times.
Next: lesson 12 finds values by a key: dictionaries and sets.
Review
3 questions from this lesson, in a new order each time. Answer from memory: 2 of 3 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
point = (3, 4)
point[0] = 5
print(point)
print((5,), (5))
def min_max(xs):
return min(xs), max(xs)
a, b = 1, 2
a, b = b, a
print(a, b)
lo, hi = min_max([7, 2, 9])
print(lo, hi)
print(min_max([7, 2, 9]))
names = ["Ada", "Alan", "Grace"]
scores = [91, 85, 78]
for place, name in enumerate(names, start=1):
print(place, name)
for i, name in enumerate(names):
print(i, name)
for name, score in zip(names, scores):
print(f"{name:<6}{score:>4}")
def low_high(xs):
# the lowest and the highest, in one loop
return 0, 0
low, high = low_high([7, 2, 9, 4])
print(low, high)
print(low_high([5]))
nums = [4, 0, 7, -2, 5, -9]
found = None
for i, n in enumerate(nums):
if n == 0:
continue
if n < 0:
found = i
break
print("checked", n)
if found is None:
print("none")
else:
print("first negative at", found)
scores = [72, 65, 48, 90, 30]
# find the first score under 50 and its place
for r in range(1, 4):
for c in range(1, 5):
print(f"{r * c:>4}", end="")
print()
n = 4
for i in range(1, n + 1):
# print the numbers 1 to i, with end=""
print()
board = []
for r in range(3):
row = []
for c in range(3):
row.append(".")
board.append(row)
board[1][0] = "X"
for row in board:
for cell in row:
print(cell, end=" ")
print()
print(board[1][0], len(board), len(board[0]))
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)
grid = []
# 1. build 4 rows of 4 numbers
# 2. print each row, each number in 3 columns
print(len(grid), "rows,", len(grid[0]), "columns")
board = [
["X", "O", "O"],
["O", "X", "O"],
["X", "X", "X"],
]
# find the first row that is all "X"
board = [
["X", "X", "O"],
["O", "X", "O"],
["X", "X", "O"],
]
wins = []
# one True or False per column
print(wins)