BYU logo Computer Science

Continue and break

We have seen lots of problems with loops. Sometimes it is helpful to break out of a loop or continue a loop.

Continue

Let’s imagine you want to find all the puppies in a grid:

None, 'p', 'p'
None, 'p', None
None, None, 'p'
'p', None, None

You could write your code like this:

def find_puppies(grid):
    rows = len(grid)
    columns = len(grid[0])
    for row in range(rows):
        for column in range(columns):
            if grid[row][column] == 'p':
                print(f'found a puppy at ({row}, {column})!')

This checks every cell in the grid to see if it contains a puppy. But we could also write the function this way:

def find_puppies(grid):
    rows = len(grid)
    columns = len(grid[0])
    for row in range(rows):
        for column in range(columns):
            if grid[row][column] != 'p':
                continue

            print(f'found a puppy at ({row}, {column})!')

Here, we focus on checking that a square does not contain a puppy, and if that is true, then we continue the loop. We won’t get to the print() statement unless a puppy is found.

If we run either version of the code:

park = [
    [None, 'p', 'p'],
    [None, 'p', None],
    [None, None, 'p'],
    ['p', None, None],
]

find_puppies(park)

it gives us the following:

found a puppy at (0, 1)!
found a puppy at (0, 2)!
found a puppy at (1, 1)!
found a puppy at (2, 2)!
found a puppy at (3, 0)!

When should you use continue?

Deciding when to use continue depends on the logic of your problem. In some cases, it can be helpful to identify the conditions where you don’t want to do anything (there is no puppy here). You can use an if statement to identify those conditions and then call continue if those conditions hold.

Break

There are some problems where you want to break out of a loop early. Imagine you want to go for a walk on a path. Along your path you may find:

  • None (Nothing) — continue on your way
  • p (a puppy) — stop and pet it
  • f (a flower) — you smell it and forget what you are doing, so you leave the path

Here is some code to do this:

def walk_the_path(path):
    for item in path:
        if item == 'p':
            print("Cute! A puppy! You spend some time petting her.")
            continue
        if item == 'f':
            print("Oh wow, a flower! You smell it. It contains a powerful chemical! You forget where you are and wander away.")
            break

        print('Darn, nothing here.')

If we find a puppy, we use continue. This goes to the next item in the path. If we find a flower, we break, which leaves the loop entirely. If we find neither of these, we finish the loop and then continue with the next iteration.

If we run this code:

row = ['p', None, None, 'p', 'f', 'p', 'p']

walk_the_path(row)

then it prints:

Cute! A puppy! You spend some time petting her.
Darn, nothing here.
Darn, nothing here.
Cute! A puppy! You spend some time petting her.
Oh wow, a flower! You smell it. It contains a powerful chemical! You forget where you are and wander away.

Breaking in nested loops

Be aware that break only gets you out of the current loop. If you are in an inner loop, then you will continue with the next iteration of the outer loop.

For example, here is a grid with puppies and bears:

park = [
    [None, 'p', 'p'],
    ['b', 'p', None],
    [None, 'b', 'p'],
    ['p', 'b', None],
]

You are going to walk through the park, picking up and rescuing puppies. But if you meet a bear, you have to run away! Because we are persistent, we run out of that row in the park but try to find more puppies on the next row.

def rescue_puppies(grid):
    rows = len(grid)
    columns = len(grid[0])
    for row in range(rows):
        for column in range(columns):
            if grid[row][column] == 'p':
                print(f'You rescued a puppy at ({row}, {column})!')
            if grid[row][column] == 'b':
                print(f'Bear! Run away!')
                break

Here, we check for a puppy and rescue it. But we also check for a bear in our second if statement, and if we find one, then we use break to get out of the inner loop (columns). However, we continue with the next iteration of the outer loop (rows).

If we run this:

park = [
    [None, 'p', 'p'],
    ['b', 'p', None],
    [None, 'b', 'p'],
    ['p', 'b', None],
]

rescue_puppies(park)

then it prints:

You rescued a puppy at (0, 1)!
You rescued a puppy at (0, 2)!
Bear! Run away!
Bear! Run away!
You rescued a puppy at (3, 0)!
Bear! Run away!

Breaking out of both loops

What if you want to break out of both the inner and outer loops? Usually, you can use return in these cases. But if you really want to do this, then you might try using some logic to help you break out of both loops.

Here is a repeat of rescue_puppies() that leaves the park entirely if we find a bear (the much more sensible thing to do):

def rescue_puppies(grid):
    rows = len(grid)
    columns = len(grid[0])
    bear = False
    for row in range(rows):
        if bear:
            break
        for column in range(columns):
            if grid[row][column] == 'p':
                print(f'You rescued a puppy at ({row}, {column})!')
            if grid[row][column] == 'b':
                print(f'Bear! Run away!')
                bear = True
                break

Notice that we use a variable bear. We set it to True if we find one in the inner loop, and we check if it is True in the outer loop.

Another example

Consider a guessing game where a person must guess a number between 1 and 10. They get 10 tries. However, there is also a trap number. If they guess the trap before they guess the correct answer, they lose. Here is some code to play this game:

import random


def guessing_game(secret, trap):
    print("Guess my number!")
    while True:
        guess = input('Your guess: ')
        guess = int(guess)
        if guess == secret:
            print("You win!")
            break
        if guess == trap:
            print("You hit the trap! You lose!")
            break

        if guess > secret:
            print("Lower :-) Guess again!")
        if guess < secret:
            print("Higher :-) Guess again!")

        guess -= 1

    print("This game has ended ...")


if __name__ == "__main__":
    numbers = range(1, 11)

    while True:
        secret = random.choice(numbers)
        trap = random.choice(numbers)

        print("Guess a number from 1 to 10! But there is a trap! Be careful!")
        guessing_game(secret, trap)
        again = input("Would you like to play again? (y/n) ")
        if again in 'Yy':
            continue
        
        break

    print("Thanks for playing!")

while true without break causes an infinite loop