Skip to content
Theory · Loops · lesson 2 of 7

The for loop and range

In the last lesson, the runner in a while loop kept count of the laps by hand. You put up the sign at the start by hand, checked the arch by hand and marked the lap counter yourself too. Forget n += 1, and the loop becomes infinite.

Now picture a judge standing by the track with a ready list of lap numbers. Before each lap, the judge hands the runner the next number. When the numbers on the list run out, the run is over. The runner no longer needs to count anything: the lap number arrives by itself.

This is how the for loop works: it takes values one by one from a ready-made series. The range function gives a series of integers. Here is the same sum from 1 to 100:

Python
total = 0
for i in range(1, 101):
    total += i
print(total)  # 5050

Let's walk through the program line by line:

  1. total = 0 sets up the sum.
  2. for i in range(1, 101): stores the next number of the series in i before each iteration.
  3. total += i adds that number to the sum.
  4. print(total) runs after the loop and prints 5050.

How for works

Before each iteration, for stores the next number of the series in the variable i: first 1, then 2, and so on. The body runs for each value. When the values run out, the loop ends, and the program moves on to the line after it.

There is no need to increase i in the body—for takes the next value by itself. So you cannot forget the counter here the way you can in while.

An object that for takes values from one at a time is called an iterable. The range function gives such an object, and a string is one too. A loop over a string goes through its characters from left to right, and on each iteration ch is a one-character string:

Python
for ch in "abc":
    print(ch, end=".")  # a.b.c.

Here the judge's list picture is inexact. The judge holds the whole list, while range stores no numbers: it computes the next one when for asks for it. That is why range(1, 1000001) takes as much memory as range(1, 11).

Three forms of range

The program below shows different forms of range. Let's go through each one.

Python
for i in range(4):
    print(i, end=" ")  # 0 1 2 3
print()
for i in range(2, 10, 4):
    print(i, end=" ")  # 2 6
print()
for i in range(5, 0, -2):
    print(i, end=" ")  # 5 3 1

A call to print() with no arguments prints only a line break, so each series comes out on its own line.

range(stop)

The form with one number gives the numbers from 0 to stop. The first loop, range(4), prints 0 1 2 3: the series starts at zero, and 4 is not part of it. You use this form to repeat an action exactly stop times.

range(start, stop)

The form with two numbers gives the numbers from start to stop. The lesson's first example is written this way: range(1, 101) starts at 1 and ends at 100. You use this form when counting does not start at zero.

range(start, stop, step)

The third number is the step: each next number is the one before plus step. In the second loop, range(2, 10, 4) gives 2 and 6. 10 would come after 6, but that is already stop, and the series breaks off there.

A negative step runs the series downward: range(5, 0, -2) gives 5, 3 and 1, and 0 is again left out.

stop is not in the series

In all three forms, stop is not part of the series: the series ends before it would reach stop. To include the last number you need, take stop one greater than it. That is why the sum up to 100 is written as range(1, 101).

Interviewers often ask how many numbers range(start, stop) gives. If stop is greater than start and the step is 1, the answer is stop - start.

If start is not less than stop with a positive step, the series is empty, and the body never runs. For example, range(5, 2) gives no numbers at all.

Common mistake

The number of iterations is computed with the / division:

Python
n = 10
for i in range(n / 2):  # ✗
    print(i)
TEXT
TypeError: 'float' object cannot be interpreted as an integer

The / operator always gives a float, here 5.0, and range accepts only integers. Floor division n // 2 gives the int 5, and the loop prints the numbers from 0 to 4.

Key points

  • for takes values one by one from an iterable: numbers from a range, characters from a string.
  • You do not change the counter in for: the loop takes the next value by itself.
  • range(start, stop, step) leaves out stop; start defaults to 0 and step to 1.
  • range accepts only integers: count iterations with //, not /.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way