6 – Loops

Introduction to Python

Author

Clemens Brunner

Published

February 5, 2025

Introduction

It is often necessary to repeat statements a certain (or undefined) number of times. For example, let’s assume that we wanted to print “Hello!” five times. Rather naively, we could write this simply as:

print("Hello")
print("Hello")
print("Hello")
print("Hello")
print("Hello")
Hello
Hello
Hello
Hello
Hello

Although this does the job, it is really cumbersome to repeat the same line of code multiple times. Furthermore, imagine we made a mistake and we really wanted to print “Bye” instead of “Hello” – we’d have to change our code in five different locations!

for-loops

Python supports two types of loops (for-loops and while-loops), which enable us to perform repeated actions. Like functions and conditions, loops control the program flow. Our previous example could be rewritten as follows:

for i in range(5):
    print("Hello")
Hello
Hello
Hello
Hello
Hello

This is obviously much shorter than writing out each repetition manually (even more so if the loop involves more iterations). Furthermore, if we want to make changes, we only need to do it once inside the body of the loop.

Let’s analyze the structure of a for-loop in Python. The first part should look familiar: just like functions and conditions, for-loops start with a header. This time, the header is introduced with the for keyword. Next, the loop header defines a name (i in our case), which will get individual values of a sequence-like object, which is specified last (range(5) in the example). In each iteration of the loop, i gets the current value of the sequence we are iterating over. A colon concludes the loop header.

The indented part after the header forms the body of the loop. This code block is what is actually repeated (in our example, print("Hello") is repeatedly called five times).

Note

Since we are not using the value of i in the loop body, it is common to use the name _ instead. Note that this is just a convention, there is nothing special about the name _ at all.

We can further inspect what’s going on by printing i inside the loop:

for i in range(5):
    print(i)
0
1
2
3
4
Tip

Note that i remains available after the loop – its value will be 4, because this was the most recent assignment in the last iteration of the loop.

Alright, so range(5) produces a sequence of five numbers, starting at 0 and ending with 4. The loop iterates over all elements of this sequence until it is exhausted, after which the loop stops. In each iteration of the loop, i contains the i-th element of the sequence, and this particular value is used when running the body of the loop.

Note

Actually, range can also be called with two arguments, which are then interpreted as start and stop values of the created range. However, the stop value does not belong to the sequence anymore (this is because the difference between stop and start is supposed to equal the number of elements):

list(range(2, 8))  # 8 - 2 = 6 values (from 2 to 7)
[2, 3, 4, 5, 6, 7]

Note that we have to use list in order to see all the elements that range creates at once (more on lists soon).

If called with a third argument, range interprets this argument as a step size:

list(range(2, 8, 2))  # values from 2 to 7, but only every second value
[2, 4, 6]

A loop can iterate not only over range, but over any sequence-like object (a data type that can contain more than one item). We will learn more about three widely-used container types (strings, lists, and dictionaries) in the next chapters.

Here’s a short preview of what a loop can do. First, we can iterate over a string:

for s in "Hello World!":
    print(s)
H
e
l
l
o
 
W
o
r
l
d
!

Here, s gets all characters of the string "Hello World!" sequentially as the loop iterates. That is, in the first iteration, s contains the character "H", in the second "e", and so on. The print function is called in each iteration with the current character s as its argument (it automatically inserts a newline at the end, though this can be changed with the end parameter).

A list is another popular sequence-like data type that can contain elements of arbitrary types (more on this later). We can iterate over a list like this:

a = ["Hello", "world!", "I", "love", "Python!"]

for element in a:
    print(element)
Hello
world!
I
love
Python!

Breaking and continuing loops

Python lets us preemptively break out of a loop or jump to the next iteration from anywhere in the loop body using the break and continue keywords, respectively.

Sometimes, we want to stop a loop early, like in the following example that demonstrates how to search for a character within a given string:

i = 0  # current position (index)

for c in "Hide and seek":
    if c == "e":  # we're searching for the first "e"
        break
    i += 1  # increment i by 1

print(i)
3

This example searches for the first occurrence of the character "e" within the string "Hide and seek". If it finds it, the name i contains the position (index) of this character within the string (3 in this example, because we initialize i with zero). Notice that once we have found the character (c == "e"), we immediately break out of the loop (which means Python immediately jumps to the end of the loop, which is the print(i) function call). As we will see soon, break is especially useful in while-loops.

Note

The statement i += 1 is shorthand for i = i + 1 (increment i by one).

The next example demonstrates the use of the continue statement, which causes Python to immediately jump back to the loop header and begin the next iteration.

for num in range(2, 10):
    if num % 2 == 0:
        print("Found an even number", num)
        continue
    print("Found an odd number", num)
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9

Of course, we could have used an else branch here, but the goal was to show an example for the continue statement.

while-loops

In addition to for-loops, Python also supports while-loops. In general, both loop types can be used interchangeably, but while-loops are especially useful when we need a loop that never stops (an infinite loop), or in cases where we don’t know in advance how many iterations we are going to perform.

Here’s our first for-loop example transformed to a while-loop:

i = 0

while i < 5:
    print(i)
    i += 1

In this case, we would prefer the for-loop, because it requires us to write only two lines of code as opposed to four lines for the while-loop.

However, while-loops are useful if we don’t know the number of iterations in advance, which is often the case when user input is involved. Consider the following example, which prompts the user to input a character and runs until the input equals "q":

while True:
    line = input("> (enter 'q' to quit) ")
    if line == "q":
        break

The while-loop makes this use case quite natural. Apparently, while True is always True, so the loop will go on forever. However, notice that there is a break statement inside the loop body, which will exit the loop immediately. This will only happen if the user input (stored in line) equals "q".

Here’s another fun little example which involves a (potentially) infinite while-loop. It also contains a condition with if, elif, and else blocks. The task of the user is to guess the value of number (which is 23 in this case, but we assume that the user doesn’t know this value). If the guess is correct, we break out of the loop and the program is done. If the user’s guess is incorrect, we give a hint and go to the next iteration.

number = 23

while True:
    guess = int(input("Enter an integer: "))  # int converts the input to a number
    if guess == number:
        print("Congratulations, you guessed it.")
        break
    elif guess < number:
        print("No, it is a little higher than that.")
    else:
        print("No, it is a little lower than that.")

Exercises

  1. Modify the number guessing game by reporting the number of guesses it took a user to guess the correct number!

  2. Iterate over the list lst = ["I", "love", "Python"] and in each iteration, print the current list element on the screen.

  3. Iterate over the list lst = ["I", "love", "Python"] and in each iteration, use a second loop to iterate over the current string and print each character on the screen followed by a -. Use the end="-" argument in print to get the desired output, which should look like this: I-l-o-v-e-P-y-t-h-o-n-.

  4. Iterate over the list [1, 13, 25, -11, 17, 24, 9, -1, 2, 3] until you encounter the first even number. Once you find this number, break out of the loop and print the number on the screen. Since we have not learned about lists yet, use a for-loop to solve this problem (we could also use a while-loop, but we need to know more about lists before we can do so).


https://creativecommons.org/licenses/by-nc-sa/4.0/ This document is licensed under the CC BY-NC-SA 4.0 by Clemens Brunner.