LambdaLabTM
Computer Science · Class 11 · Iterative Statements
IterationCount known⏱️ 12 min read

The for Loop

The loop for when the number of rounds is known before it starts. You hand it a collection of values — usually from range() — and it takes them one at a time, runs the block once for each, and stops when they run out. There is no counter for you to move and none to forget.

1How it is written

shape.py
for variable in collection:
    statement
    statement
next statement

Three parts to notice. for and in are both keywords, and both are compulsory. The name between them is the loop variable — you choose it, and Python creates it for you. After the colon comes the usual indented block.

hello5.py
# printing hello 5 times
for i in range(1, 6):
    print('hello')
Output
hello
hello
hello
hello
hello

range(1, 6) produces 1, 2, 3, 4, 5 — five values — so the block runs five times. The loop variable i is not used inside the block here; it is still there, quietly taking each value in turn.

2What Python actually does

Six steps, and every one of them matters:

  1. Work out the collection: range(1, 6) becomes the values 1, 2, 3, 4, 5.
  2. Create the loop variable — here, i.
  3. Take the next value from the collection and put it in i.
  4. Jump into the body and run it.
  5. At the end of the body, go back up to the header.
  6. Repeat 3 to 5 until there are no values left. Then the loop ends and the program carries on below it.

Step 5 is the one that makes it a loop, and it is invisible in the code — nothing on the page points back upwards. Step through it below and watch the pointer make that jump:

🔁 One round at a time

Step through the loop and watch where i comes from.

values still waiting
12344 left
table.py
headerbody — the indented blockoutside
n = 7
for i in range(1, 5):
print(n, 'x', i, '=', n * i)
the loop variable
i =

i is an ordinary variable, and you never assign to it yourself. Each round the header takes the next value from the ones range() made and puts it in i. That goes on until no value is left to hand out — and then the loop ends.

output
nothing yet

The header runs first. range(1, 5) is worked out into the values 1, 2, 3, 4, and the loop variable i is created — empty for now.

Key Takeaway
The loop variable is an ordinary variable, and you never assign to it yourself — the header does it. Each round it takes the next value from the ones range() made and puts it in the variable. That carries on until every value has been handed out and none is left; then the loop ends, and Python moves to the first statement outside the body. And you can use that variable in the body — which is what turns “do this five times” into “do this to each of these five things”.

3Using the loop variable

The moment the body mentions i, every round does something different:

rounds.py
# the loop variable is a real variable — you can use its value
for i in range(1, 6):
    print('Round', i)
Output
Round 1
Round 2
Round 3
Round 4
Round 5

Which is all a multiplication table is:

Input
what we ask the user for
  • the number whose table is wanted
Process
what we work out
  • count i from 1 to 10
  • each round, work out n * i
Output
what we show
  • one line per round
table.py
# the table of a number entered by the user
n = int(input('Enter a number: '))

for i in range(1, 11):
    print(n, 'x', i, '=', n * i)
Output
Enter a number: 7
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

range(1, 11), not range(1, 10) — because stop is excluded, and the table needs the 10.

4Building up an answer across the rounds

A variable made before the loop survives every round, so the loop can add to it a little at a time. This is how a program totals things:

sum_n.py
# the sum of all the numbers from 1 to n
n = int(input('Enter a number: '))
s = 0

for i in range(1, n + 1):
    s = s + i

print('Sum =', s)
Output
Enter a number: 5
Sum = 15

Two placements decide whether this works. s = 0 is above the loop, so it happens once — inside, it would reset to 0 every round and the total would never grow past the last number. And print() is at the margin, so it happens after the loop is done — indented, it would print a running total on every round.

Watch Out
Above the loop, inside it, or after it. Those three places are the commonest source of a loop that runs perfectly and answers the wrong question. Before you write a line, ask: does this need doing once at the start, once per round, or once at the end?

5for without range()

range() is the commonest thing to loop over, not the only one. A for loop will walk through any sequence — a string, a list, a tuple — handing you one item at a time:

over_string.py
# a for loop can walk through a string, one character at a time
name = 'Asha'

for ch in name:
    print(ch)
Output
A
s
h
a
over_list.py
# ... or through a list, one item at a time
marks = [72, 91, 65]

for m in marks:
    print('Mark:', m)
Output
Mark: 72
Mark: 91
Mark: 65

Notice there is no counting and no indexing here. The loop variable holds the item itself — the character, the mark — not its position. This is the form to reach for whenever the question is “do something to each one”.

6What goes wrong

The colon and the indentation fail exactly as they did with if, and the messages name the statement:

for_no_indent.py
for i in range(1, 6):
print('hello')
Output
  File "for_no_indent.py", line 2
    print('hello')
    ^
IndentationError: expected an indented block after 'for' statement on line 1

The one that is new belongs to for alone. The thing after in has to be something with values in it. A plain number is not:

not_iterable.py
for i in 5:
    print('hello')
Output
Traceback (most recent call last):
  File "not_iterable.py", line 1, in <module>
    for i in 5:
TypeError: 'int' object is not iterable

Iterable means “can be gone through one item at a time”. A string, a list, a tuple and a range all can. The number 5 cannot — to repeat five times, ask for range(5), which turns the 5 into five values.

7Try it

Run the table, then change range(1, 11) to range(1, 6), then to range(10, 0, -1). Then replace the range with a list of your own.

table.py

8Recap

Key Takeaway
for variable in collection: runs its block once for every value in the collection, putting each value into the loop variable in turn. It ends when the values run out, so it cannot run for ever. The collection is usually a range(), but any sequence — string, list, tuple — works the same way.
Quick Check

How many times does the body of 'for i in range(1, 6):' run?

Quick Check

In the sum program, what happens if s = 0 is written inside the loop instead of above it?

Quick Check

What does 'for ch in 'Asha':' put into ch on the second round?