print("Opening drawer 1")
print("Opening drawer 2")
print("Opening drawer 3")Opening drawer 1
Opening drawer 2
Opening drawer 3
Programs often need to repeat the same instructions. We could write the same code several times:
print("Opening drawer 1")
print("Opening drawer 2")
print("Opening drawer 3")Opening drawer 1
Opening drawer 2
Opening drawer 3
This works for three drawers, but it would be tedious for 100. Loops allow us to describe the repetition once and let Python perform it.
for LoopA for loop takes values one at a time and executes the same block of code for each value.
for drawer_number in range(1, 4):
print("Opening drawer", drawer_number)Opening drawer 1
Opening drawer 2
Opening drawer 3
Python executes the loop three times:
| Iteration | Value of drawer_number |
Output |
|---|---|---|
| First | 1 | Opening drawer 1 |
| Second | 2 | Opening drawer 2 |
| Third | 3 | Opening drawer 3 |
The general structure is:
for <element> in <sequence>:
<code>The loop executes its <code> once for each <element> in the <sequence>. Notice the colon and the indentation. The indentation tells Python which instructions belong to the loop.
Without running the code, write down exactly what it will print.
for level in range(1, 4):
print("Starting level", level)
print("Ready!")
print("Game finished")Starting level 1
Ready!
Starting level 2
Ready!
Starting level 3
Ready!
Game finished
The two indented instructions run three times. The final instruction is outside the loop, so it runs only once.
range() with For LoopsPython provides a built-in function called range() that generates a sequence of integers. We can use it when a loop needs to count.
With range(<start>, <stop>), Python starts at <start> and stops before <stop>:
for num in range(1, 6):
print(num)1
2
3
4
5
This prints 1, 2, 3, 4, and 5. The stopping value 6 is not included.
We can write range(<stop>) too. In this case, the sequence starts at 0:
for num in range(5):
print(num)0
1
2
3
4
This prints 0, 1, 2, 3, and 4.
We can also specify the step between values with range(<start>, <stop>, <step>):
for num in range(1, 11, 3):
print(num)1
4
7
10
This prints 1, 4, 7, and 10.
A negative step lets us count backwards:
for num in range(5, 0, -1):
print(num)
print("Lift-off!")5
4
3
2
1
Lift-off!
Write a countdown from 10 to 1. After the loop finishes, print Lift-off!.
for second in range(10, 0, -1):
print(second)
print("Lift-off!")10
9
8
7
6
5
4
3
2
1
Lift-off!
A video-game character needs level ** 2 * 100 experience points to complete each level. Print the experience required for levels 1 to 10.
The first lines should be:
Level 1 requires 100 XP
Level 2 requires 400 XP
Level 3 requires 900 XP
for level in range(1, 11):
experience = level ** 2 * 100
print(f"Level {level} requires {experience} XP")Level 1 requires 100 XP
Level 2 requires 400 XP
Level 3 requires 900 XP
Level 4 requires 1600 XP
Level 5 requires 2500 XP
Level 6 requires 3600 XP
Level 7 requires 4900 XP
Level 8 requires 6400 XP
Level 9 requires 8100 XP
Level 10 requires 10000 XP
So far, range() has supplied numbers to our loops. A for loop can also work with a collection of values, such as a string.
# Loop through the characters in a string
for letter in "Python":
print(letter)P
y
t
h
o
n
There exists a wide variety of sequences in Python. We will explore them in detail in the second module. For now, we will briefly introduce lists, which are one of the most common ways to store a collection of values.
A list is an ordered collection of elements. The elements can be numbers, strings, Booleans, or other data types.
# A list of numbers
numbers = [1, 2, 3, 4, 5]
print(numbers)[1, 2, 3, 4, 5]
We will explain lists in detail later in this course. For now, it is enough to know that we create lists using brackets [].
mixed_list = [1, "b", True, 4]
print(mixed_list)[1, 'b', True, 4]
When a for loop uses a list, the loop variable receives each element in order:
planets = ["Mercury", "Venus", "Earth", "Mars"]
for planet in planets:
print("Visiting", planet)Visiting Mercury
Visiting Venus
Visiting Earth
Visiting Mars
The code inside the loop does not have to use the current element:
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print("I do not care about the number")I do not care about the number
I do not care about the number
I do not care about the number
I do not care about the number
I do not care about the number
The message is printed five times because the list contains five elements.
Create a list with the names of four students. Use a for loop to print a welcome message for each student.
For example: Welcome, Ada!
students = ["Ada", "Grace", "Guido", "Linus"]
for student in students:
print(f"Welcome, {student}!")Welcome, Ada!
Welcome, Grace!
Welcome, Guido!
Welcome, Linus!
Many times when we work with loops, we want to update one of our variables. Remember that variables can be reassigned.
For instance, let us make a sentence from a list of words:
list_words = ["Hello", "my", "name", "is", "Daniel"]
# We initialize the output variable as an empty string
sentence = ""
# Add each word to the sentence
for word in list_words:
sentence = sentence + word
print(sentence)Hello
Hellomy
Hellomyname
Hellomynameis
HellomynameisDaniel
The value stored in sentence is preserved between iterations. Each iteration adds something to its previous value.
How would you add spaces to that sentence?
list_words = ["Hello", "my", "name", "is", "Daniel"]
sentence = ""
for word in list_words:
sentence = sentence + word + " "
print(sentence.strip())Hello my name is Daniel
The same pattern can accumulate numbers:
total = 0
for number in range(1, 6):
total = total + number
print(f"After adding {number}, the total is {total}")
print("Final total:", total)After adding 1, the total is 1
After adding 2, the total is 3
After adding 3, the total is 6
After adding 4, the total is 10
After adding 5, the total is 15
Final total: 15
A videogame boss begins with 100 health points. The player attacks five times, and every attack causes 18 points of damage.

After every attack, print the attack number and the boss’s remaining health.
boss_health = 100
for attack in range(1, 6):
boss_health = boss_health - 18
print(f"Attack {attack}: the boss has {boss_health} HP")Attack 1: the boss has 82 HP
Attack 2: the boss has 64 HP
Attack 3: the boss has 46 HP
Attack 4: the boss has 28 HP
Attack 5: the boss has 10 HP
Write a program to compute the factorial of any positive integer.
\[5! = 5 \cdot 4 \cdot 3 \cdot 2 \cdot 1\]
num = 5
result = 1
for value in range(1, num + 1):
result = result * value
print(result)120
We can combine if statements and for loops. The loop controls which value we are processing, and the condition decides what to do with that value.
for number in [-2, -1, 0, 1, 2]:
if number < 0:
print(f"{number} is negative")
else:
print(f"{number} is zero or positive")-2 is negative
-1 is negative
0 is zero or positive
1 is zero or positive
2 is zero or positive
Scan rooms 1 to 20. Print Scanning room <number> for most rooms. If the room number is divisible by 7, print Warning: alien detected in room <number> instead.
for room in range(1, 21):
if room % 7 == 0:
print(f"Warning: alien detected in room {room}")
else:
print(f"Scanning room {room}")Scanning room 1
Scanning room 2
Scanning room 3
Scanning room 4
Scanning room 5
Scanning room 6
Warning: alien detected in room 7
Scanning room 8
Scanning room 9
Scanning room 10
Scanning room 11
Scanning room 12
Scanning room 13
Warning: alien detected in room 14
Scanning room 15
Scanning room 16
Scanning room 17
Scanning room 18
Scanning room 19
Scanning room 20
Write code that finds all factors of any given positive integer.
A factor is an integer that divides the given number without leaving a remainder.
num = 52
for factor in range(1, num + 1):
if num % factor == 0:
print(f"{factor} is a factor of {num}")1 is a factor of 52
2 is a factor of 52
4 is a factor of 52
13 is a factor of 52
26 is a factor of 52
52 is a factor of 52
We can include a loop inside another loop. This is called a nested loop.
Imagine searching several pieces of furniture. For each piece of furniture, you inspect every drawer:
furniture = ["desk", "wardrobe", "bedside table"]
for item in furniture:
print(f"Searching the {item}")
for drawer in range(1, 4):
print(f"Opening drawer {drawer}")Searching the desk
Opening drawer 1
Opening drawer 2
Opening drawer 3
Searching the wardrobe
Opening drawer 1
Opening drawer 2
Opening drawer 3
Searching the bedside table
Opening drawer 1
Opening drawer 2
Opening drawer 3
The inner loop finishes all three drawers before the outer loop moves to the next piece of furniture. With three pieces of furniture and three drawers in each, the instruction inside the inner loop runs \(3 \times 3 = 9\) times.
What output do you expect from this loop? Answer before running the code.
for number in range(3):
for letter in ["a", "b", "c"]:
print(number, letter)The loop prints every combination of the numbers 0, 1, 2 with the letters a, b, c, in that order.
0 a
0 b
0 c
1 a
1 b
1 c
2 a
2 b
2 c
A treasure map has four rows and five columns. Use nested loops to inspect every position and print its coordinates:
Searching position 1 1
Searching position 1 2
...
Searching position 4 5
The treasure is at row 3, column 4. When the program reaches that position, also print Treasure found!.
for row in range(1, 5):
for column in range(1, 6):
print("Searching position", row, column)
if row == 3 and column == 4:
print("Treasure found!")Searching position 1 1
Searching position 1 2
Searching position 1 3
Searching position 1 4
Searching position 1 5
Searching position 2 1
Searching position 2 2
Searching position 2 3
Searching position 2 4
Searching position 2 5
Searching position 3 1
Searching position 3 2
Searching position 3 3
Searching position 3 4
Treasure found!
Searching position 3 5
Searching position 4 1
Searching position 4 2
Searching position 4 3
Searching position 4 4
Searching position 4 5
A cinema has three rows with four seats in each row. Print a label for every seat, such as Row 2, seat 3.
Before writing the program, answer:
for row in range(1, 4):
for seat in range(1, 5):
print(f"Row {row}, seat {seat}")Row 1, seat 1
Row 1, seat 2
Row 1, seat 3
Row 1, seat 4
Row 2, seat 1
Row 2, seat 2
Row 2, seat 3
Row 2, seat 4
Row 3, seat 1
Row 3, seat 2
Row 3, seat 3
Row 3, seat 4
The outer loop represents the rows, the inner loop represents the seats, and the program prints \(3 \times 4 = 12\) labels.
The command break stops a loop immediately. We usually use it with an if statement.
for <element> in <sequence>:
if <condition>:
break
<code>Suppose we are searching drawers for some missing keys. Once we find them, there is no reason to continue searching:
drawers = ["notebooks", "cables", "keys", "old photos"]
for contents in drawers:
print("Checking", contents)
if contents == "keys":
print("Keys found!")
breakChecking notebooks
Checking cables
Checking keys
Keys found!
Notice that old photos is never checked.
for number in range(10):
if number > 5:
print("Stop!")
break
print(number)0
1
2
3
4
5
Stop!
break stops only one loop. In a nested loop, breaking the inner loop does not stop the outer loop.
for number in range(5):
for letter in ["a", "b", "c"]:
print(letter)
if letter == "b":
# This break stops only the loop over letters
breaka
b
a
b
a
b
a
b
a
b
Write a program that receives a list of numbers and adds them until the sum reaches or exceeds a threshold. Print the result and the number at which the loop stopped.
list_numbers = [1, 3, 4, 5, 7, 9]
threshold = 10
result = 0
for number in list_numbers:
result = result + number
if result >= threshold:
print(f"Stopped at {number}. Result is {result}")
breakStopped at 5. Result is 13
Fix the following code.
# Multiply odd numbers until the result is higher than n
n = 1000
result = 0
for i in range(n):
if i % 2 == 1:
result = result * i
if result > n:
break
print(result)The multiplication never gets started because multiplying by 0 keeps the result at 0. Initialize the result at 1, and begin the range at 1.
n = 1000
result = 1
for i in range(1, n):
if i % 2 == 1:
result = result * i
if result > n:
break
print(result)10395
The command continue stops the current iteration and jumps to the next one.
for <element> in <sequence>:
<code1>
if <condition>:
continue
<code2>The loop always executes <code1>. If the condition is met, it jumps to the next element and skips <code2>.
for num in range(5):
# This always happens
print(num)
# If the number is 2, skip the next instruction
if num == 2:
continue
# This happens for all numbers except 2
print(f"{num} x 2 = {num * 2}")0
0 x 2 = 0
1
1 x 2 = 2
2
3
3 x 2 = 6
4
4 x 2 = 8
Read the code below and, without running it, predict which numbers will be printed.
for n in range(1, 10):
sqn = n ** (1 / 2)
if sqn % 1 == 0:
continue
print(n)Perfect squares are skipped, so the loop prints:
2
3
5
6
7
8
A for loop works well when we have a sequence of values to process. Sometimes we do not know beforehand how many repetitions we will need. In that case, a condition can control the repetition.
A while loop repeatedly executes a block of code as long as a condition is True.
while <condition>:
<code># Count from 1 to 5
num = 1
while num <= 5:
print(num)
num = num + 11
2
3
4
5
The variable involved in the condition must normally change inside the loop. Otherwise, the loop may never end.
num = 1
# This loop will never end
while num > 0:
num = num + 1
print(num)If you run an infinite loop, stop the execution by clicking the stop button next to the cell.
Write a program that receives a list of numbers and adds them until the sum reaches or exceeds a threshold. Print the result and the number at which the loop stopped. Use a while loop.
list_numbers = [1, 3, 4, 5, 7, 9]
threshold = 10
result = 0
index = 0
while result < threshold and index < len(list_numbers):
current_number = list_numbers[index]
result = result + current_number
index = index + 1
if result >= threshold:
print(f"Stopped at {current_number}. Result is {result}")
else:
print("The list ended before the threshold was reached")Stopped at 5. Result is 13
For each problem, decide whether a for loop or a while loop is more natural.
1, 4, 9, 16, ....for: the number of values is fixed at 50.for: the number of terms is fixed at 20.while: we do not know how many terms it will take to pass 999.for: the range of candidates is fixed.while: we know how many primes we want, but not how many integers we must test before finding them.while: the number of divisions is not known beforehand.while: the number of repetitions depends on the intermediate results.for: the number of square numbers is fixed at 15.Try to code some of these exercises. If you get stuck, first trace a small example by hand. You may also ask Gemini for a hint, but ask for one hint at a time before requesting a complete solution.
# Code the exercises hereWhy do the following while loops never end?
i = 1
while i != 0:
print(f"The value of i={i} is not zero.")
i += 1n = 2
while n % 2 == 0:
print(f"n is still even: {n}")
n = n * 2i = 1
while i > 0:
i = i // 2
print(f"i is now: {i}")
i += 1The first loop keeps increasing i, so it never becomes 0.
The second loop keeps doubling an even number, so it always remains even.
The third loop changes i to 0 and immediately adds 1, so the condition i > 0 remains true.
Ask the user for a height and print a staircase of that height. For a height of 5:
#
##
###
####
#####
Hint: Python can repeat a string. For example, "#" * 3 produces "###".
height = int(input("Height: "))
for row in range(1, height + 1):
print("#" * row)Print the numbers from 1 to 30, with these changes:
Fizz instead of the number.Buzz instead of the number.FizzBuzz.Think carefully about the order of your conditions.
for number in range(1, 31):
if number % 15 == 0:
print("FizzBuzz")
elif number % 3 == 0:
print("Fizz")
elif number % 5 == 0:
print("Buzz")
else:
print(number)1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
When you feel ready, test your knowledge by working through the review exercises.
Work through the “Looping” homework exercises available here. To earn participation credit, complete the exercises highlighted in red.