Course outline · 0% complete

0/32 lessons0%

Course overview →

for and range

lesson 5-1 · ~11 min · 13/32

Recall from lesson 2-1 that indexing starts at 0, so for s = "loop" the value of s[0] is "l", the first character.

That numbering is about to matter again. Loops and indexes work together constantly, and the for loop in this lesson visits a string's characters in exactly the same order those index numbers describe, starting at the front and moving one position at a time.

for: do something for each item

Loops are the reason computers beat hand work. Check 10,000 rows, resize every photo in a folder, send a message to every subscriber: each is a few lines repeated automatically. From here on, nearly every useful program you write in this course, and on the job, has a loop in the middle.

A for loop runs its indented body once per item in a sequence. A string is a sequence, so this visits every character:

for ch in "abc":
    print(ch)

ch is the loop variable: Python assigns it the next character before each pass through the body.

range: a sequence of numbers on demand

When you want to repeat something N times or count, use range():

  • range(5) produces 0, 1, 2, 3, 4 (starts at 0, stops before 5)
  • range(2, 6) produces 2, 3, 4, 5
  • range(0, 10, 2) produces 0, 2, 4, 6, 8 (the third number is the step)

The stop value is excluded, exactly like string slices in lesson 2-1. range(5) has 5 items, which makes repeat 5 times read naturally.

Three loops, three sequences

Each loop below runs its body once per item. Counting the output lines against the range rules above is the quickest way to internalize them.

for ch in "abc":
    print(ch)
for i in range(3):
    print("beep", i)
for i in range(2, 6):
    print(i)

Output

a
b
c
beep 0
beep 1
beep 2
2
3
4
5

The first loop treats the string as a sequence of characters and makes three passes. The second shows why range(5) means five repetitions: range(3) yields 0, 1, and 2, three values that stop before the number given. The third supplies both ends and produces 2 through 5, stopping before 6, so it makes four passes rather than the five a careless reading of 2, 6 might suggest.

next item left?run the bodygo back and check againno items left: leave the loop
One loop iteration: take the next item, run the body, come back, check again. The gold dot traces the cycle.

A times table is the standard first use of a counting loop, with the loop variable appearing twice in each line of output.

for i in range(1, 6):
    print(f"5 x {i} = {5 * i}")

Output

5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25

The range starts at 1 because the table does, and it stops at 6 so that 5 is the last value included. Getting that upper bound right is the usual stumbling point, since range(1, 5) would quietly print only four rows. Inside the body, one set of braces shows i itself while the other computes 5 * i, so a single f-string produces the whole line.

Counting downward with a negative step

A negative third argument makes range count down instead of up. Here it starts at 10 and subtracts 2 each pass.

for i in range(10, 0, -2):
    print(i)

Output

10
8
6
4
2

The stop value is still excluded, which is why the sequence ends at 2 and never reaches 0. That is easy to get wrong when counting down, because a loop meant to include 0 would need range(10, -1, -2). The rule does not change with direction: the loop stops as soon as the next value would pass the boundary.