range() Function
Concepts covered: Iteration
A for loop needs a sequence to walk. When the sequence you want is a run of numbers, range() builds it for you. range(5) produces 0, 1, 2, 3, 4: it starts at 0, climbs by 1, and stops before 5. The number you pass is the stop, and the stop itself is never produced.
# Print 0 to 4
for i in range(5):
print(i)0 1 2 3 4
The loop makes 5 passes, one per number, and the last printed value is 4. This lines up with how positions are counted in Python: the first position is 0, so the 5 positions of a 5-item sequence are 0 through 4, and range(5) produces exactly those 5 numbers.
Start, stop and step
range() accepts 1, 2 or 3 numbers. A single number is the stop, and the start defaults to 0. Given 2, range reads them as the start and the stop. A third number is the step: how far each produced number is from the one before it. A negative step counts down.
| Call | Produces | How many |
|---|---|---|
| range(5) | 0, 1, 2, 3, 4 | 5 |
| range(2, 6) | 2, 3, 4, 5 | 4 |
| range(0, 10, 2) | 0, 2, 4, 6, 8 | 5 |
| range(10, 0, -3) | 10, 7, 4, 1 | 4 |
| range(3, 3) | nothing | 0 |
| range(5, 2) | nothing | 0 |
The stop stays excluded in every form. range(2, 6) ends at 5. range(10, 0, -3) keeps producing values while they are above 0, so 1 is the last one and -2 is never reached. range(5, 2) uses the default step of 1 and can't climb from 5 to a value below 2, so it produces nothing, and a loop over it runs its body 0 times without an error.
for i in range(2, 6):
print("i is", i)
for i in range(10, 0, -3):
print("down to", i)Output:
i is 2 i is 3 i is 4 i is 5 down to 10 down to 7 down to 4 down to 1
Repeating something n times
Sometimes the numbers themselves are beside the point and you want the body to run a fixed number of times. range(3) still produces 0, 1 and 2, but the body never reads them. The convention is to name the variable _ to signal to anyone reading the code that nothing uses it.
for _ in range(3):
print("Knock")Getting the stop right
When a sum should run from 1 to 10 inclusive, the stop is 11. Being off by 1 at the stop is the most common range mistake. The fix is a question: which value should be the last one produced? Pass 1 more than that as the stop. For a step of 2 running from 0 to 20 inclusive, the stop is 21, and 20 is the last value produced.
total = 0
for n in range(1, 11):
total = total + n
print("1 to 10 sums to", total)
evens = 0
for n in range(0, 21, 2):
evens = evens + 1
print(evens, "even numbers from 0 to 20")Output:
1 to 10 sums to 55 11 even numbers from 0 to 20
How many lines does this loop print?
for i in range(3, 12, 4):
print(i)- 2 lines: 3 and 7
- 4 lines: 3, 7, 11 and 15
- 3 lines: 3, 7 and 11
- 9 lines: 3 through 11
Working backwards from a wanted sequence to a range call takes 3 readings. The first value is the start. The gap between neighbours is the step. The stop is any number past the last value and at most 1 step beyond it, and last value + 1 is the safe choice. For 3, 6, 9 that gives range(3, 10, 3).
A countdown reads the same way with a negative step. The start is the first number printed and the step is -1. The excluded stop now sits on the low side, so it goes 1 below the last number you want: to end on 3, stop at 2. range(9, 2, -1) produces 9 down to 3.
About this lesson
This section is part of the Loops: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.