Did you know: programmers convert coffe to code?

If you like my articles, support me with a small amount.


Buy me a coffee

Loops

Loops allow to loop through the program code and repeat blocks of code until a given condition is fulfilled or not fulfilled. The code which is repeated is called the loop’s body.

This article is an excerpt of my book Python 3 in Anger. For a more detailed version take a look at the book.

Python has two types of loops: the for loop and the while loop.

Loops have variables which change their values in every execution of the loop’s body and these variables have to be used as a condition either in the loop’s head or in the body to break the flow.

If you do not have a terminating condition in your loop you might end up with an infinite or endless loop which never terminates and you have to kill your application manually. Most of these loops are achieved with while constructs. Let me show you examples:

while True:
    print('I love Python!')

i = 0
while i < 1:
    print('I love Python!')

In the fists example you have a condition in the head of the loop which evaluates always to True thus the program will print I love Python to the console forever. This loop would never terminate.

The second loop is a bit more tricky because I use a variable in the head of the loop. This loop would eventually terminate if the value of i would be greater than 1 at one time. However because the loop’s body does only printing to the console this will never happen.

Let’s look at the loop types in detail to see how loops work and how we can avoid endless loops.

And one more nice thing about loops: they can handle an else block which gets executed if the condition in the loop’s head is not fulfilled anymore. This is a new programming construct which seems strange to programmers of a classic programming language where the loops do not have an else part.

Modifying the control flow in the loop’s body

Before we can go into the details of the loops we need to learn about two constructs which modify the loops’ control flow. These are break and continue. Let’s see how they work in general and then with examples in the sections about the loops themselves.

break

The break statement, as its name suggests, breaks out of the loop. Most of the time it is within a conditional block to stop the loop if it should not be continued anymore.

This statement ends the loop right away, so no more statements are executed — not in the loop’s body after the break statement and the else part of the loop isn’t executed too.

while / for some_condition:
    execute_this
    do_this
    break
    this_does_not_executed
    this_neither
else:
    this_is_leaved_behind
    this_too

In the example above I did not include any if conditional to break out of the loop to demonstrate the working of the statement.

continue

Parallel to the break statement you can tell the loop to continue the execution at the head again. This means any other statement behind the continue statement does not get executed, however the loop continues until the condition in the loop’s head evaluates to False. In this case the else block of the loop is executed when the lopp finished.

while / for some_condition:
    execute_this
    do_this
    continue
    this_does_not_executed
    this_neither
else:
    this_is_executed_at_the_end
    this_too

Now we are ready to take a look at the loops themselves with examples. Are you ready? Why not?

for loops

The for loop is designed to iterate over collections or to execute the loop’s body a finite amount of times. The general syntax of the loop looks like this:

for variable in sequence:
    statement_1
    statement_2
    ...
    statement_n
else:
    else_statement_1
    else_statement_2
    ...
    else_statement_m

Naturally the else block is optional as only one statement is required in the body of the for loop.

Let’s have a real example:

>>> for m in menu:
...     print(m)
... else:
...    print("What do you want?")
...
eggs
sausage
bacon
spam
What do you want?

In the example above the for loop iterates over the elements of the list and prints out every element to the console. After the loop is finished the else block is executed once.

range

In the example above it seems really bothersome to define the list of numbers every time again-and-again. This is Python so there has to be some construct which leverages this from the developer. And there it is: the range function.

The function requires one parameter: the stop value; and two optional parameters: start and step.

If only stop is provided then the range function generates a range from the number 0 until the stop number (the stop number is not included) with the step of 1.

>>> for i in range(10):
...     print(i)
...
0
1
2
3
4
5
6
7
8
9

As you can see in the example above the numbers are printed from 0 to 9 with a step of 1.

If the start parameter is provided then the range function creates a range between the start and the stop number (again, the stop number is exlusive).

If the start number is greater or equal than the stop number then the loop is not executed.

>>> for i in range(15,20):
...    print(i)
...
15
16
17
18
19
>>> for i in range(25,10):
...    print(i)
...

The step defines how many elements to leave out — or to step over the numbers between start and stop even if the start number is greater than the stop number. In this case you have to provide the step of -1.

>>> for i in range(1,10,2):
...    print(i)
...
1
3
5
7
9
>>> for i in range(10,1,-1):
...    print(i)
...
10
9
8
7
6
5
4
3
2

As you can see, the range function is used to execute the loop a finite amount of times.

for loop with break and continue

Now we know the basics of a for loop let’s add the already known control-flow modifications: break and continue.

As I have told you previously if you use break the whole loop is terminated. Do you remember the sample for loop from the beginning of this section? Now let’s add a conditional to it to break when the element we iterate through is "spam":

>>> menu = ['eggs', 'sausage', 'bacon', 'spam']
>>> for m in menu:
...     if m == 'spam':
...         break
...     print(m)
... else:
...    print("What do you want?")
...
eggs
sausage
bacon
>>> menu = ['eggs', 'sausage', 'bacon', 'spam']
>>> for m in menu:
...     print(m)
...     break
... else:
...    print("What do you want?")
...
eggs

Continue jumps back to the head of the loop in the case of a for loop it jumps to the next element of the collection. If the collection is empty then the loop finishes and the else loop is executed. Let’s see again two examples: one with a conditional continue and one with a continue of its own.

>>> menu = ['eggs', 'sausage', 'bacon', 'spam']
>>> for m in menu:
...     if m == 'spam':
...         continue
...     print(m)
... else:
...    print("What do you want?")
...
eggs
sausage
bacon
What do you want?
>>> menu = ['eggs', 'sausage', 'bacon', 'spam']
>>> for m in menu:
...     continue
...     print(m)
... else:
...    print("What do you want?")
...
What do you want?

As you can see, the main difference between continue and break is in the flow of the loop: the first one jumps back and iterates over the remaining elements, the second one terminates the whole loop. Naturally you can combine both together to have the right control flow of your own.

for loop with side-effects

Naturally you can have side-effects when using a for loop with a list. That’s because the collection you iterate over is not immutable so you can change its value during the loop — which can result in unexpected behavior. Let’s see an example:

>>> l = ['eggs']
>>> for e in l:
...     if e == 'eggs':
...         l += ['sausage']
...     if e == 'sausage':
...         l += 'spam'
...     print(e)
...
eggs
sausage
s
p
a
m
>>> l
['eggs', 'sausage', 's', 'p', 'a', 'm']

As you can see we modified the list during the execution of the for loop so when the loop finished and returned to the head for evaluation it found new elements in the list so the loop continued to execute.

To avoid this we can use a copy of the list to iterate over in the loop:

>>> l = ['eggs']
>>> for e in l[:]:
...     if e == 'eggs':
...         l += ['sausage']
...     if e == 'sausage':
...         l += 'spam'
...     print(e)
...
eggs

while loops

The while loop is designed to execute the loop’s body an indefinite amount of time until a condition is reached. With the for loop you can execute the loop’s body only a finite amount of timmes (depending on the list or the range you provide to it).

And because the while loop need a conditional statement you can easily create an infinite loop (as seen in the introduction to loops).

Let’s see how a while loop is built up:

while condition_evaluates_to_True:
    statement_1
    statement_2
    ...
    statement_n
else:
    else_statement_1
    else_statement_2
    ...
    else_statement_m

As you can see the structure is almost the same as by a for loop however here you need a boolean condition wihch evaluates to True. The else block is the same and executes when the loop terminates normally. If a break encounters in the loop’s body then the else block is not executed.

>>> i = 0
>>> while i < 10:
...     i += 1
... else:
...     print("Finished loop, i has the value of ", i)
...
Finished loop, i has the value of  10

The main usage of a while loop is in games or applications with user interaction for example where you need to get a specific type of input (for example a number) or want to execute logic until the game ended. Let’s see a simple example where we ask the user for numeric input.

while True:
    try:
        a = int(input('Enter a number: '))
    except ValueError:
        print("This was not a number!")
        continue
    break

print("You entered: ", a)

As you can see in this example, if the user does not enter a number then the application prints out “This was not a number!” and because of the continue statement it executes the loop again. If the input can be converted tu a number then the break statement terminates the endless while loop.

If you run the application you might get something like this:

Enter a number: enter
This was not a number!
Enter a number: a
This was not a number!
Enter a number: number
This was not a number!
Enter a number: 23j
This was not a number!
Enter a number: 42
You entered:  42

while loop with break and continue

>>> i = 0
>>> while i < 10:
...     continue
...     i += 1
... else:
...     print("Finished loop, i has the value of ", i)
...

This code won’t stop because i is never incremented so after calling continue the expression i < 10 is evaluated again and again to False so the loop executes infinitely. If you started the example above, you can stop it with hitting CTRL-C on the keyboard.

&gt;&gt;&gt; i = 0
&gt;&gt;&gt; while i &gt;&gt; i
0

As you can see, when using break the else block is not executed. And in the example above the value of i did not change at all.

Naturally these are just basic examples with break and continue, most of the time you use them in a conditional expression.

GHajba
 

Senior developer, consultant, author, mentor, apprentice. I love to share my knowledge and insights what I achieve through my daily work which is not trivial -- at least not for me.

Click Here to Leave a Comment Below 0 comments