More loops

By Martin McBride, 2018-08-05
Tags: for loop range while loop break continue else nested loop
Categories: python language beginning python


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 creates a clear separation of 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 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 a 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.

See also

If you found this article useful, you might be interested in the book NumPy Recipes or other books by the same author.

Join the PythonInformer Newsletter

Sign up using this form to receive an email when new content is added:

Popular tags

2d arrays abstract data type alignment and angle animation arc array arrays bar chart bar style behavioural pattern bezier curve built-in function callable object chain circle classes clipping close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data science data types decorator design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop formula function function composition function plot functools game development generativepy tutorial generator geometry gif global variable gradient greyscale higher order function hsl html image image processing imagesurface immutable object in operator index inner function input installing iter iterable iterator itertools join l system lambda function latex len lerp line line plot line style linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map marker style matplotlib monad mutability named parameter numeric python numpy object open operator optimisation optional parameter or pandas partial application path pattern permutations pie chart pil pillow polygon pong positional parameter print product programming paradigms programming techniques pure function python standard library radial gradient range recipes rectangle recursion reduce regular polygon repeat rgb rotation roundrect scaling scatter plot scipy sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template tex text text metrics tinkerbell fractal transform translation transparency triangle truthy value tuple turtle unpacking user space vectorisation webserver website while loop zip zip_longest