Python informer

Improve your Python coding skills

More loops

Introduction

In this lesson we will look at some extra loop techniques:

  • The break operator
  • The continue operator
  • Using else with a for loop
  • Nested loops statements

The break operator

You can terminate loops early, or skip part of a loop body, using break or continue.

Break in a for loop

Here is a simple game to try to think of different animals:

print("Name 10 animals, one per line")

for i in range(10):
    s = input('> ')
    print('Animal', i, s)

print('Well done!')

The problem here is that you might want a way to quit the program before typing in ten animals - after all it is quite a boring game. So perhaps you should be allowed to type in “quit” to stop the game early.

But you can’t stop a for loop. It will just loop ten times whatever happens. That is where break comes in:

print("Name 10 animals, one per line")

for i in range(10):
    s = input('> ')
    if s=='quit':
        break
    print('Animal', i, s)

print('Well done!')

If the user types in “quit”, the break statement executes. This causes the loop to stop immediately, and execute the first line after the loop - print(‘Well done!').

Break in a while loop

The structure of a while loop is quite different from a for loop. Each time through the loop, you get to test one or more conditions to decide if to continue. So why do you need break?

Here is an example where we ask the user a question, and only give them 3 chances to answer:

question = 'What is the capital of Italy?'
answer = 'Rome'
maxTries = 3

tries = 0
response=''
while response != answer and tries < maxTries:
    print(question)
    response = input()
    tries += 1
print('Finished')

In this case, there are two different reasons for quitting the loop - either the answer is correct, or you got it wrong three times. These reasons are separate things, but they appear in the same statement. And they use negative logic (loop again if the answer is not correct and you have not had too many tries). If you had a more complex loop, with three or four different escape conditions, it could get quite hard to follow.

break allows us to structure the loop differently, to separate out the different conditions for terminating the loop:

question = 'What is the capital of Italy?'
answer = 'Rome'
maxTries = 3

tries = 0
while True:
    print(question)
    response = input()
    if response == answer:
        break
    tries += 1
    if tries >= maxTries:
        break;
print('Finished')

First thing is that the loop condition is True. This means that the loop will never finish - the condition to continue is always true. So the only way out of the loop is by breaking out using a break statement.

Using the break conditions clearly separates the two different cases. Although the code is slightly longer, it is easier to see what is going on. It also gives you the chance to handle each exit differently, for example by printing a different message:

question = 'What is the capital of Italy?'
answer = 'Rome'
maxTries = 3

tries = 0
while True:
    print(question)
    response = input()
    if response == answer:
        print('That is correct')
        break
    tries += 1
    if tries >= maxTries:
        print('Sorry, you ran out of tries')
        break;
    print('Wrong answer, try again')
print('Finished')

The continue operator

continue can be used in either a for or while loop. If it is executed, it will skip the rest of the loop body and jump straight to the next iteration. For example here is the code to print out a popular children’s rhyme:

for i in range(1, 8):
    print(i, end=' ')
    if i == 4:
        print()
        continue
    print('potato', end=' ')
print('more')

This prints out:

1 potato 2 potato 3 potato 4
5 potato 6 potato 7 potato more

The point here is that every number except four should have the word “potato” after it. Using continue causes the rest of the loop (ie the code which prints “potato”) to be skipped.

If you are wondering why we couldn’t just use an if statement, well we could:

for i in range(1, 8):
    print(i, end=' ')
    if i != 4:
        print('potato', end=' ')
    else
        print()
print('more')

The difference here is that an if statement simply tells you that you will be missing some of the loop. A continue statement makes it totally clear that you are going to skip all of the rest of the loop. Once again, this makes the code a little more readable by showing exactly what the purpose of the code is.

Using else with a for loop

Here is some code to work out the smallest factor of n. That is, the lowest number that divides into n:

n = 247
for i in range(2, n):
    if not n % i:
        print(n, 'is divisible by', i)
        break

% is the modulo operator. This code relies on the fact that n % i is zero if and only if i is factor of n. We start the loop value at 2 because all numbers divide by 1.

If you run this code, you will discover that 247 divides by 13. But if you try it again with 239, the code prints nothing, because 239 has no factors - it is prime.

It would be nice if our loop could print something out when n is prime. We need some way of detecting whether the loop hit a break condition (meaning that n has a factor), or whether the loop terminates normally (meaning that n is prime). This is where an else clause helps:

n = 239
for i in range(2, n):
    if not n % i:
        print(n, 'is divisible by', i)
        break
else:
    print(n, 'is prime')

The else clause is executed after the end of the for loop, but only if it terminates normally. If the loop terminates due to a break statement, the else clause is not executed.

Nested loops statements

Here is a simple example of a nested loop:

for i in range(1, 5):
    print("Run", i)
    for j in range(5, 0, -1)
        print(j)

In this case, the outer loop (using counter i) runs 4 times. Each time the inner loop (using j) counts down from 5 to 1. This means that j is printed a total of 20 times. Try it and see.

Printing times tables

Here is some code to print the 2 times table, using a for loop:

print('2 TIMES TABLE')
print('--------------')
for a in range(1, 13):
    print(a, 'times 2 is', a*2)

In the code below, we have changed the inner loop to print the b times table. We run this in an outer loop that prints all the times tables from 2 to 12.

for b in range(2, 13):
    print(b, 'TIMES TABLE')
    print('--------------')
    for a in range(1, 13):
        print(a, 'times', b, 'is', a*b)
    print()

Here the inner loop prints a single times table, the outer loop prints each separate table in turn. Notice how the code that prints the title is only indented one level as it is part of the outer loop.