DekGenius.com
[ Team LiB ] Previous Section Next Section

10.2 break, continue, pass, and the Loop else

Now that we've seen our first Python loop, we should introduce two simple statements that have a purpose only when nested inside loops—the break and continue statements. We will also study the loop else clause here because it is intertwined with break, and Python's empty placeholder statement, the pass. In Python:


break

Jumps out of the closest enclosing loop (past the entire loop statement)


continue

Jumps to the top of the closest enclosing loop (to the loop's header line)


pass

Does nothing at all: it's an empty statement placeholder


Loop else block

Runs if and only if the loop is exited normally—without hitting a break

10.2.1 General Loop Format

Factoring in break and continue statements, the general format of the while loop looks like this:

while <test1>:
    <statements1>
    if <test2>: break         # Exit loop now, skip else.
    if <test3>: continue      # Go to top of loop now.
else:
    <statements2>             # If we didn't hit a 'break'

break and continue statements can appear anywhere inside the while (and for) loop's body, but they are usually coded further nested in an if test, to take action in response to some sort of condition.

10.2.2 Examples

Let's turn to a few simple examples to see how these statements come together in practice. The pass statement is used when the syntax requires a statement, but you have nothing useful to say. It is often used to code an empty body for a compound statement. For instance, if you want to code an infinite loop that does nothing each time through, do it with a pass:

while 1: pass   # Type Ctrl-C to stop me!

Since the body is just an empty statement, Python gets stuck in this loop.[1] pass is roughly to statements as None is to objects—an explicit nothing. Notice that the while loop's body is on the same line as the header, after the colon; as in the if, this only works if the body isn't a compound statement.

[1] This code does nothing, forever. It probably isn't the most useful Python program ever written, unless you want to test a CPU meter, or warm up your laptop computer on a cold winter's day. Frankly, though, we couldn't think of a better pass example. We'll see other places where it makes sense later in the book (for instance, in Chapter 22, to define empty classes that implement objects that behave like "structs" and "records" in other languages).

The continue statement is an immediate jump to the top of a loop. It sometimes lets you avoid statement nesting; the next example uses continue to skip odd numbers. This code prints all even numbers less than 10 and greater than or equal to 0. Remember, 0 means false, and % is the remainder-of-division operator, so this loop counts down to zero, skipping numbers that aren't multiples of two (it prints 8 6 4 2 0):

x = 10
while x:
    x = x-1                   # Or, x -= 1
    if x % 2 != 0: continue   # Odd?--skip print
    print x,

Because continue jumps to the top of the loop, you don't need to nest the print statement inside an if test; the print is only reached if the continue is not run. If this sounds similar to a "goto" in other languages it should; Python has no goto statement, but because continue lets you jump about in a program, many of the warnings about readability and maintainability you may have heard about goto apply. continue should probably be used sparingly, especially when you're first getting started with Python; the example above, for instance, might be clearer if the print were nested under the if:

x = 10
while x:
    x = x-1
    if x % 2 == 0:            # Even?-- print
        print x,

The break statement is an immediate loop exit. Because code below it is never reached, the break can also sometimes avoid nesting. For example, here is a simple interactive loop, which inputs data with raw_input, and exits when the user enters "stop" for the name request:

>>> while 1:
...     name = raw_input('Enter name:')
...     if name == 'stop': break
...     age  = raw_input('Enter age: ')
...     print 'Hello', name, '=>', int(age) ** 2
...
Enter name:mel
Enter age: 40
Hello mel => 1600
Enter name:bob
Enter age: 30
Hello bob => 900
Enter name:stop

Notice how this code converts the age input to an integer before raising it to the second power, with int; raw_input returns user input as a string. In Chapter 22, you'll see that it also raises an exception on end-of-file (e.g., if users type Ctrl-Z or Ctrl-D); if it matters, wrap raw_input in try statements.

When combined with the loop else, the break statement can often eliminate the search status flags used in other languages. For instance, the following piece of code determines if a positive integer number y is prime by searching for factors greater than 1:

x = y / 2                          # For some y > 1
while x > 1:
    if y % x == 0:                 # Remainder
        print y, 'has factor', x
        break                      # Skip else
    x = x-1
else:                              # Normal exit
    print y, 'is prime'

Rather than setting a flag to be tested when the loop is exited, insert a break where a factor is found. This way, the loop else can assume that it will be executed only if no factor was found; if you don't hit the break, the number is prime.[2]

[2] More or less. Numbers less than 2 are not considered prime by the strict mathematical definition. To be really picky, this code also fails for negatives, fails for floating-point numbers, and will be broken by the future / "true" division change mentioned in Chapter 4. If you want to experiment with this code, be sure to see the exercise at the end of Part IV, which wraps it in a function.

The loop else is also run if the body of the loop is never executed, since you don't run a break in that event either; in a while loop, this happens if the test in the header is false to begin with. In the example above, you still get the "is prime message" if x is initially less than or equal to 1 (e.g., if y is 2).

10.2.3 More on the Loop else

Because the loop else clause is unique to Python, it tends to perplex some newcomers on first glance. In more general terms, the loop else provides explicit syntax for a common coding scenario—it is a coding structure that lets you catch the "other" way out of a loop, without setting and checking flags or conditions.

Suppose, for instance, that you are writing a loop to search a list for a value, and need to know whether the value was found after you exit the loop. You might code such a task this way:

found = 0
while x and not found:
    if match(x[0]):              # Value at front?
        print 'Ni'
        found = 1
    else:
        x = x[1:]                # Slice off front and repeat.
if not found:
    print 'not found'

Here, we initialize, set, and later test a flag, to know if the search succeeded or not. This is valid Python code, and does work; but it's exactly the sort of structure that the loop else is there to handle. Here's an else equivalent:

while x:                         # Exit when x empty.
    if match(x[0]):
        print 'Ni'
        break                    # Exit, go around else.
    x = x[1:]
else:
    print 'Not found'            # Only here if exhausted x.

Here, the flag is gone, and we replaced the if test at loop end with an else (lined up vertically with the word while, by indentation). Because the break inside the main part of the while exits the loop and goes around the else, this serves as a more structured way to catch the search failure case.

Why You Will Care: Emulating C while Loops

The section on expression statements stated that Python doesn't allow statements such as assignments to appear in places where it expects an expression. This means a common C language coding pattern won't work in Python:

while ((x = next(  )) != NULL) {...process x...}

C assignments return the value assigned; Python assignments are just statements, not expressions. This eliminates a notorious class of C errors (you can't accidentally type = in Python when you mean ==). But if you need similar behavior, there are at least three ways to get the same effect in Python while loops, without embedding assignments in loop tests. You can move the assignment into the loop body with a break:

while 1:
    x = next(  )
    if not x: break
    ...process x...

move the assignment into the loop with tests:

x = 1
while x:
    x = next(  )
    if x:
        ...process x...

or move the first assignment outside the loop:

x = next(  )
while x:
    ...process x...
    x = next(  )

Of these three coding patterns, the first may be considered by some to be the least structured, but seems to also be the simplest and most commonly used. A simple Python for loop may replace some C loops as well.


Some readers might notice that the prior example's else could be replaced with a test for an empty x after the loop (e.g., if not x:). Although that's true in this example, the else provides explicit syntax for this coding pattern (it's more obviously a search failure clause here), and such an explicit empty test may not apply in some cases. Moreover, the loop else becomes even more useful when used in conjunction with the for loop, because sequence iteration is not under your control.

    [ Team LiB ] Previous Section Next Section