Online Book Reader

Home Category

Learning Python - Mark Lutz [193]

By Root 1940 0
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 -= 1

else: # Normal exit

print(y, 'is prime')

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

The loop else clause is also run if the body of the loop is never executed, as 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. Thus, in the preceding example you still get the “is prime” message if x is initially less than or equal to 1 (for instance, if y is 2).

* * *

Note


This example determines primes, but only informally so. Numbers less than 2 are not considered prime by the strict mathematical definition. To be really picky, this code also fails for negative numbers and succeeds for floating-point numbers with no decimal digits. Also note that its code must use // instead of / in Python 3.0 because of the migration of / to “true division,” as described in Chapter 5 (we need the initial division to truncate remainders, not retain them!). 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 for reuse.

* * *

More on the loop else

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

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

found = False

while x and not found:

if match(x[0]): # Value at front?

print('Ni')

found = True

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 determine whether the search succeeded or not. This is valid Python code, and it does work; however, this is exactly the sort of structure that the loop else clause 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

This version is more concise. The flag is gone, and we’ve replaced the if test at the loop end with an else (lined up vertically with the word while). 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.

Some readers might have noticed that the prior example’s else clause 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. The loop else becomes even more useful when used in conjunction with the for loop—the topic of the next section—because sequence iteration is not under your control.

* * *

Why You Will Care: Emulating C while Loops


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

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

C assignments return the value assigned, but 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 ==). If you need similar behavior, though, there are at least three ways to get the same effect in Python while loops without embedding assignments

Return Main Page Previous Page Next Page

®Online Book Reader