Definite repetition with range() — counting, totals, averages, string iteration, and simple formatted reports
Chapter 8 introduced the while loop: a loop that keeps running as long as a condition is true. You learned how to initialize variables, update them inside the loop body, and give the loop a clear path toward stopping.
This chapter introduces the for loop. A for loop is Python's tool for repeating work a definite number of times, or for stepping through every item in a sequence one by one. Where a while loop asks keep going as long as this is true, a for loop asks do this once for each thing in this collection.
You will learn how the for loop works, how to use range() to control it, how to count up and count down, how to compute totals and averages, how to step through the characters of a string, and how to design simple formatted reports. You will also learn how to choose between a for loop and a while loop when both could work. By the end of this chapter you will be able to read, trace, and write for loops confidently — and you will be ready for lists, files, and data processing in later chapters.
By the end of this chapter, you should be able to:
for loop does and how it differs from a while loop.range() with one, two, or three arguments to produce a desired sequence of integers.range(), including with a step value.for loop to perform a repeated calculation, such as a conversion table.for loop.for loop or a while loop is the better tool for a given problem.for loop errors, including off-by-one mistakes.for Loop DoesDefinite repetition; the for-loop structure; comparing for and while versions of the same loop; reading a loop as a sentencerange() FunctionOne, two, and three-argument forms; the excluded stop value; range as a sequence description, not a list; tracing range() callsfor and whileDefinite versus indefinite repetition; deciding rule; side-by-side comparisonfor Loop ErrorsOff-by-one mistakes; accumulator placement errors; modifying the loop variable; string-versus-index confusion; indentation errorsfor Loop DoesA for loop repeats a block of code a definite number of times, or once for every item in a sequence.
Here is the simplest possible example:
for i in range(5):
print(i)
0 1 2 3 4
Five lines. Five numbers. The loop ran exactly five times, once for each value that range(5) produced.
Compare this to a while loop that does the same thing:
i = 0
while i < 5:
print(i)
i = i + 1
Both programs produce identical output. But notice what the for version does not need: it does not need you to initialize i before the loop, and it does not need you to update i at the bottom of the loop body. The for loop handles both of those things automatically.
This is the central practical advantage of a for loop when you know in advance how many times something should repeat. The loop takes care of the bookkeeping so you can focus on the body.
for variable in sequence:
body
The word for starts the loop. The variable receives each value from the sequence, one at a time. The colon ends the header. The indented body runs once for each value. When the sequence is exhausted, the loop ends and Python moves on.
It helps to read a for loop as a sentence: "For each value of i in range(5), print i." This reading reminds you that the loop is stepping through a collection — not just counting.
for loop works the same way: it picks up each value from the sequence, uses it in the body, and moves to the next one.range() FunctionMost for loops over numbers use range() to generate the sequence of values. range() is a built-in function that produces a series of integers.
range() With One Argumentrange(n)
Produces integers from 0 up to but not including n.
for i in range(4):
print(i)
0 1 2 3
The upper boundary is never included. range(4) gives 0, 1, 2, 3 — four values.
range(n) gives n values, starting at 0.
range() With Two Argumentsrange(start, stop)
Produces integers from start up to but not including stop.
for i in range(3, 8):
print(i)
3 4 5 6 7
range() With Three Argumentsrange(start, stop, step)
Produces integers from start up to but not including stop, advancing by step each time.
for i in range(0, 10, 2):
print(i)
0 2 4 6 8
The step controls how far the value jumps between iterations.
range() does not produce a list. It produces a range object — a description of a sequence. Python generates each value on demand as the loop runs, rather than storing all the values in memory at once. For small loops this makes no practical difference, but it is good to know that range(1000000) does not create a million numbers in memory.
Before writing a loop, it helps to ask: what values will range() produce here?
| Call | Values Produced |
|---|---|
range(5) | 0, 1, 2, 3, 4 |
range(1, 6) | 1, 2, 3, 4, 5 |
range(0, 10, 3) | 0, 3, 6, 9 |
range(5, 0, -1) | 5, 4, 3, 2, 1 |
range(10, 0, -2) | 10, 8, 6, 4, 2 |
Practice predicting these before the next section.
Many problems count from 1 rather than 0. Use a two-argument range():
for i in range(1, 6):
print(i)
1 2 3 4 5
Count from 10 through 20:
for i in range(10, 21):
print(i)
The stop value is 21, not 20, because the boundary is excluded.
Count the multiples of 5 from 5 through 50:
for i in range(5, 51, 5):
print(i)
5 10 15 20 25 30 35 40 45 50
Use a negative step:
for i in range(5, 0, -1):
print(i)
5 4 3 2 1
This is a countdown. Note that the stop value 0 is excluded, so the sequence ends at 1.
A countdown to zero:
for i in range(3, -1, -1):
print(i)
3 2 1 0
The stop value is -1 so that 0 is included in the sequence.
number = 7
for i in range(1, 11):
print(i, "x", number, "=", i * number)
1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49 8 x 7 = 56 9 x 7 = 63 10 x 7 = 70
The loop variable i does double duty: it counts the iterations and it participates in the calculation.
The variable that appears after for is called the loop variable. On each iteration, Python assigns it the next value from the sequence.
for temperature in range(20, 26):
print("Temperature:", temperature, "°C")
Temperature: 20 °C Temperature: 21 °C Temperature: 22 °C Temperature: 23 °C Temperature: 24 °C Temperature: 25 °C
The loop variable is named temperature here instead of i to make the code easier to read. The name i is fine for a generic counter, but when the loop variable has a clear meaning, a meaningful name is better.
After a for loop finishes, the loop variable still exists and holds the last value it was assigned:
for i in range(1, 4):
print(i)
print("Loop ended. i is now:", i)
1 2 3 Loop ended. i is now: 3
This is rarely useful, but it is good to know so you are not surprised if you see a loop variable used after the loop.
You can read the loop variable inside the loop body, but modifying it does not change how the loop iterates. Python reassigns the loop variable from the sequence at the start of each iteration, regardless of what you do inside the body.
for i in range(3):
print("Before:", i)
i = 100 # This does not skip ahead
print("After:", i)
Before: 0 After: 100 Before: 1 After: 100 Before: 2 After: 100
The loop still ran three times, with i starting as 0, 1, and 2 on each iteration. Assigning i = 100 changed the value for that iteration only.
| Name | Typical Use |
|---|---|
i | generic integer counter |
n | when counting toward n |
count | when counting events |
index | when tracking position |
value | when the value is what matters |
| descriptive names | always preferred when the meaning is clear |
for loops are excellent for performing the same calculation many times, possibly with different inputs each time.
for i in range(1, 8):
square = i * i
print(i, "squared is", square)
1 squared is 1 2 squared is 4 3 squared is 9 4 squared is 16 5 squared is 25 6 squared is 36 7 squared is 49
Convert Celsius to Fahrenheit for a range of temperatures.
print("Celsius Fahrenheit")
print("------- ----------")
for celsius in range(0, 45, 5):
fahrenheit = (celsius * 9 / 5) + 32
print(celsius, " ", fahrenheit)
Celsius Fahrenheit ------- ---------- 0 32.0 5 41.0 10 50.0 15 59.0 20 68.0 25 77.0 30 86.0 35 95.0 40 104.0
The header row is printed once before the loop. The loop then prints one row per iteration.
Show how a savings account grows over five years at 4% annual interest.
balance = 1000.00
rate = 0.04
print("Year Balance")
print("---- -------")
for year in range(1, 6):
balance = balance + balance * rate
print(year, " ", round(balance, 2))
Year Balance ---- ------- 1 1040.0 2 1081.6 3 1124.86 4 1169.86 5 1216.65
Each iteration updates balance and prints the new value. The variable balance persists across iterations because it is defined outside the loop body.
Two of the most common for loop patterns are computing a total and computing an average.
An accumulator starts at zero and adds to itself on each iteration.
total = 0
for i in range(1, 6):
total = total + i
print("Total:", total)
Trace:
| Iteration | i | total before | total after |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 3 |
| 3 | 3 | 3 | 6 |
| 4 | 4 | 6 | 10 |
| 5 | 5 | 10 | 15 |
Total: 15
This is the sum of 1 + 2 + 3 + 4 + 5.
A counter starts at zero and increases by 1 on each iteration that meets a condition.
count = 0
for i in range(1, 21):
if i % 3 == 0:
count = count + 1
print("Multiples of 3 between 1 and 20:", count)
Multiples of 3 between 1 and 20: 6
An average requires both a total and a count. For a loop over a fixed range(), the count is simply the number of iterations.
total = 0
count = 0
for score in range(60, 96, 5):
total = total + score
count = count + 1
average = total / count
print("Average:", average)
Average: 77.5
Add all even numbers from 2 through 100.
total = 0
for i in range(2, 101, 2):
total = total + i
print("Sum of even numbers from 2 to 100:", total)
Sum of even numbers from 2 to 100: 2550
If the accumulator is never set before the loop, Python raises a NameError the first time the loop body tries to use it. Always initialize your accumulator to 0 (or the appropriate starting value) before the loop begins.
# This will cause a NameError
for i in range(1, 6):
total = total + i # 'total' is not defined yet
The accumulator must be initialized once, outside the loop. If it is reset inside the loop body, it never accumulates anything across iterations.
# This resets total every iteration — total never grows
for i in range(1, 6):
total = 0 # Wrong: this runs every iteration
total = total + i
print(total) # Always prints 5, not 15
A for loop can step through the characters of a string one by one. You will work with strings in much more depth in Chapter 16, but it is useful to see strings and for loops together now.
word = "Python"
for character in word:
print(character)
P y t h o n
The loop variable character receives each character of the string "Python" in order, from left to right. The loop runs six times because "Python" has six characters.
Count how many times the letter 'a' appears in a word:
word = "banana"
count = 0
for character in word:
if character == "a":
count = count + 1
print("Number of a's:", count)
Number of a's: 3
Print each character with its position number. Use range() with the length of the string:
word = "hello"
for i in range(len(word)):
print("Position", i, ":", word[i])
Position 0 : h Position 1 : e Position 2 : l Position 3 : l Position 4 : o
len(word) returns the number of characters in the string. range(len(word)) produces 0, 1, 2, 3, 4 — valid positions in the string.
Do not worry too much about indexing yet — Chapter 16 covers it thoroughly. The point here is that for loops work with strings, not just numbers.
Direct iteration (stepping through each character) is simpler when you only need each character:
for character in word:
print(character)
Index-based iteration is necessary when you also need to know the position:
for i in range(len(word)):
print(i, word[i])
Use the simpler form when it is enough.
One practical use of for loops is generating repeated output in a consistent format — what we might call a simple report.
Print a line of dashes:
for i in range(20):
print("-", end="")
print()
--------------------
The end="" argument to print() suppresses the newline that print() normally adds, so all twenty dashes appear on one line. The final print() with no arguments adds the newline at the end.
Print a simple grade report:
print("=" * 30)
print("Student Grade Report")
print("=" * 30)
print(f"{'Name':<15} {'Grade':>10}")
print("-" * 30)
names = ["Alice", "Bob", "Carmen", "David"]
grades = [92, 78, 85, 90]
for i in range(4):
print(f"{names[i]:<15} {grades[i]:>10}")
print("=" * 30)
============================== Student Grade Report ============================== Name Grade ------------------------------ Alice 92 Bob 78 Carmen 85 David 90 ==============================
This preview uses lists, which you will study in Chapter 17. For now, the key idea is that a for loop generates many rows of output in a consistent format with very little code.
n = int(input("Which times table? "))
print()
print(f"Times table for {n}")
print("-" * 20)
for i in range(1, 13):
print(f"{i} x {n} = {i * n}")
If the user enters 6:
Times table for 6 -------------------- 1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36 7 x 6 = 42 8 x 6 = 48 9 x 6 = 54 10 x 6 = 60 11 x 6 = 66 12 x 6 = 72
Twelve rows. One loop. No repetition.
A loop inside a loop can generate a grid of output. This is called a nested loop. The outer loop controls the rows; the inner loop controls the columns.
for row in range(1, 4):
for col in range(1, 4):
print(row * col, end=" ")
print()
1 2 3 2 4 6 3 6 9
end=" ").print() moves to the next line.Nested loops are powerful, but they can get complicated quickly. Keep them simple while you are learning.
for and whileBoth for and while loops repeat code. Knowing which to use is an important judgment call.
Examples for for: iterating over range(10), printing a times table, computing the sum of the numbers 1 through n, stepping through each character in a string.
Examples for while: asking a user to keep entering numbers until they type "done", repeating until a correct password is entered, running until a game is over.
# for: print numbers 1 through 5
for i in range(1, 6):
print(i)
# while: print numbers 1 through 5
i = 1
while i <= 5:
print(i)
i = i + 1
Both work. The for version is shorter and clearer when you know the range in advance.
# while: keep asking until valid input
response = input("Enter a number greater than zero: ")
while not response.isdigit() or int(response) <= 0:
response = input("Invalid. Try again: ")
A for loop cannot naturally express "keep going until the user gives a valid response," because you do not know how many tries it will take. Use while.
If you can answer "exactly how many times should this loop run?" before the loop starts, use for. If you cannot, use while.
for Loop ErrorsEven simple for loops have common mistake patterns. Learning to recognize them saves debugging time.
# Intended: print 1 through 5
for i in range(5): # Wrong: produces 0, 1, 2, 3, 4
print(i)
Fix: use range(1, 6). Remember: range(n) starts at 0, not 1. If you want 1 through n, use range(1, n + 1).
# Intended: print 10 through 20 inclusive
for i in range(10, 20): # Wrong: stops at 19
print(i)
Fix: use range(10, 21). The stop value is always excluded. Add 1 to include it.
for i in range(1, 6):
total = 0 # Wrong: resets every iteration
total = total + i
print(total)
Fix:
total = 0 # Correct: initialized once before the loop
for i in range(1, 6):
total = total + i
print(total)
for i in range(10):
if i == 3:
i = 7 # This does not jump to iteration 7
print(i)
0 1 2 7 4 5 6 7 8 9On the iteration where
i starts as 3, the body changes i to 7 and prints 7. But then the next iteration starts, and i becomes 4 as normal. Changing the loop variable inside the body does not skip or repeat iterations.
# How many times does this loop run?
for i in range(3, 9, 2):
print(i)
3 5 7Three times, not six. The sequence is
3, 5, 7 — three values. When using a step, count the values explicitly rather than assuming.
# Intended: count from 5 down to 1
for i in range(5, 1, -1): # Produces 5, 4, 3, 2
print(i)
The 1 is excluded. Fix: use range(5, 0, -1) to produce 5, 4, 3, 2, 1.
word = "hello"
for i in word:
print(i + 1) # TypeError: can't add str and int
When iterating directly over a string, the loop variable holds a character (a string), not an integer index. You cannot add a number to it. If you need numeric positions, use range(len(word)).
for i in range(5):
total = total + i
print(i) # Wrong: this line is outside the loop
versus
for i in range(5):
total = total + i
print(i) # Correct: this line is inside the loop
Python uses indentation to define what is inside the loop body. A line that is not indented is not part of the loop and runs only once, after the loop finishes.
A for loop repeats a block of code once for each value in a sequence. The sequence is most commonly produced by range(), but it can also be a string or, in later chapters, a list or other collection.
range() accepts one, two, or three arguments: a stop value, a start and stop value, or a start, stop, and step value. The stop value is always excluded. range(n) produces n values starting at 0.
The loop variable receives each value from the sequence at the start of each iteration. It can be used inside the loop body, but modifying it does not change how the loop iterates.
Accumulators — variables initialized before the loop that are updated inside the body — are the standard way to compute totals, counts, products, and averages with a for loop.
for loops can also step through the characters of a string, one character at a time.
Use a for loop when you know in advance how many times the loop should run. Use a while loop when the number of iterations depends on conditions that arise during execution.
Common for loop errors include off-by-one mistakes in range() calls, initializing accumulators inside the loop, and confusing character iteration with index-based iteration.
In the next chapter you will consolidate everything you have learned about control flow — conditionals, while loops, and for loops — through systematic tracing, debugging, and test design.
For each program below, trace the execution carefully and write out the complete output.
for i in range(6):
print(i * 2)
for i in range(1, 8, 2):
print(i)
total = 0
for i in range(1, 5):
total = total + i
print("i =", i, " total =", total)
print("Final total:", total)
for i in range(5, 0, -1):
print(i, "...")
print("Go!")
word = "loop"
for ch in word:
print(ch.upper())
count = 0
for i in range(1, 21):
if i % 4 == 0:
count = count + 1
print(count)
for row in range(1, 4):
for col in range(1, 4):
print(row + col, end=" ")
print()
Exercise 8 — Write the range() call that produces each sequence.
Exercise 9 — How many times does each loop run? Write the count without running the code.
for i in range(10):for i in range(3, 10):for i in range(0, 20, 4):for i in range(10, 1, -1):for i in range(5, 5):for i in range(1, 10, 3):Exercise 10 — Write the range() call for each description.
for loop to compute and print the sum of all integers from 1 through 100.1 that multiplies rather than adds.n, then prints the sum and average of all integers from 1 through n.Exercise 15 — A program is supposed to compute the average of the numbers 10, 20, 30, 40, and 50 using a for loop over range(10, 51, 10). It should print 30.0. The student wrote this:
for i in range(10, 51, 10):
total = 0
total = total + i
average = total / 5
print(average)
Each program below contains one or more errors. Identify the error(s) and write the corrected version.
# Intended: print 1 through 10
for i in range(10):
print(i)
# Intended: print even numbers from 2 through 20
for i in range(2, 20, 2):
print(i)
# Intended: count down from 10 to 1
for i in range(10, 0):
print(i)
# Intended: print the sum of 1 through 5
for i in range(1, 6):
total = 0
total = total + i
print(total)
# Intended: count characters equal to 'e' in "believe"
word = "believe"
count = 0
for i in range(len(word)):
if word == "e":
count = count + 1
print(count)
# Intended: print a 3-row, 3-column grid of asterisks
for row in range(3):
for col in range(3):
print("*")
print()
1 squared = 1, 2 squared = 4, and so on.n and prints a countdown from n to 1, followed by "Launch!".for loop to compute and print the value of 2 raised to each power from 0 through 10. Print each line as 2^0 = 1, 2^1 = 2, and so on."code", the output should be 1: c, 2: o, 3: d, 4: e.for loop. (Hint: use min_score and max_score variables that you update on each iteration.)Background. A teacher wants a program that produces a formatted report showing the grade and status for each student score in a set. You will build this report generator using a for loop.
1. The program should use a fixed list of test scores:
scores = [88, 72, 95, 61, 83, 77, 90, 55, 68, 79]
names = ["Alice", "Bob", "Carmen", "David", "Elena",
"Frank", "Grace", "Henry", "Isla", "James"]
2. The program should print a formatted report with:
3. Use this grading scale:
========================================
Student Grade Report
========================================
Name Score Grade Status
----------------------------------------
Alice 88 B Pass
Bob 72 C Pass
Carmen 95 A Pass
David 61 D Fail
Elena 83 B Pass
Frank 77 C Pass
Grace 90 A Pass
Henry 55 F Fail
Isla 68 D Fail
James 79 C Pass
========================================
Total students : 10
Students passed : 7
Students failed : 3
Class average : 76.8
Highest score : 95
Lowest score : 55
========================================
Start by printing just the header. Then write the loop that prints one row per student with the correct grade. Then add the accumulation logic to compute the summary statistics. Write and test one piece at a time.
Modify the program so that it also prints the names of the students who failed, in a section titled "Students who need follow-up:".
for loop and a while loop? Give one example situation where you would use each.Question 32 — A student writes:
total = 0
for i in range(1, 11):
total + i
print(total)
The program prints 0. Explain the bug.
Question 33 — What does this program print? Trace it carefully.
result = 1
for i in range(1, 5):
result = result * i
print(result)
if, elif, and else.0. It should then print the sum and count of all the non-zero integers entered. Use a while loop.range(2, 9, 3) produce? List the values.True. A loop runs while the variable is True. Inside the loop, the variable is never changed. What kind of loop problem is this?for loop to print all multiples of 7 from 7 through 70 in a single line separated by spaces.for loop?range(n) produce? What value does it start at?range() start at a value other than 0?range() control?for loop?for to step through a string by index?for instead of while? When should you use while instead of for?range() boundaries cause this mistake?range()?range(5, 5) is used in a for loop, how many times does the loop body run?Chapter 9 completes the core loop topics of Part II. You now have the three fundamental tools of control flow: conditionals, while loops, and for loops. Chapter 10 brings everything together. Instead of learning new syntax, you will develop stronger habits of thinking: how to trace a complete program using a tracing table, how to classify and read Python error messages, how to design test cases and edge cases, and how to find and fix bugs systematically. These skills will make every program you write from this point forward cleaner, more reliable, and easier to improve.