A program’s control flow is the order in which the program’s code executes. The control flow of a Python program is regulated by conditional statements, loops, and function calls. (This section covers the if
statement and for
and while
loops; functions are covered in Functions.) Raising and handling exceptions also affects control flow; exceptions are covered in Chapter 6.
Often, you need to execute some statements only if some condition holds, or choose statements to execute depending on several mutually exclusive conditions. The Python compound statement if
, comprising if
, elif
, and else
clauses, lets you conditionally execute blocks of statements. Here’s the syntax for the if
statement:
if expression: statement(s) elif expression: statement(s) elif expression: statement(s) ... else: statement(s)
The elif
and else
clauses are optional. Note that, unlike some languages, Python does not have a switch
statement. Use if
, elif
, and else
for all conditional processing.
Here’s a typical if
statement with all three kinds of clauses:
if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative"
When there are multiple statements in a clause (i.e., the clause controls a block of statements), the statements are placed on separate logical lines after the line containing the clause’s keyword (known as the header line of the clause), indented rightward from the header line. The block terminates when the indentation returns to that of the clause header (or further left from there). When there is just a single simple statement, as here, it can follow the :
on the same logical line as the header, but it can also be on a separate logical line, immediately after the header line and indented rightward from it. Most Python programmers prefer the separate-line style, with four-space indents for the guarded statements. Such a style is considered more general and more readable.
if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative"
You can use any Python expression as the condition in an if
or elif
clause. Using an expression this way is known as using it “in a Boolean context.” In a Boolean context, any value is taken as either true or false. As mentioned earlier, any nonzero number or nonempty container (string, tuple, list, dictionary, set) evaluates as true; zero (of any numeric type), None
, and empty containers evaluate as false. When you want to test a value x
in a Boolean context, use the following coding style:
if x:
This is the clearest and most Pythonic form. Do not use any of the following:
if x is True: if x == True: if bool(x):
There is a crucial difference between saying that an expression returns True
(meaning the expression returns the value 1
with the bool
type) and saying that an expression evaluates as true (meaning the expression returns any result that is true in a Boolean context). When testing an expression, you care about the latter condition, not the former.
If the expression for the if
clause evaluates as true, the statements following the if
clause execute, and the entire if
statement ends. Otherwise, Python evaluates the expressions for each elif
clause, in order. The statements following the first elif
clause whose condition evaluates as true, if any, execute, and the entire if
statement ends. Otherwise, if an else
clause exists, the statements following it execute.
The while
statement in Python supports repeated execution of a statement or block of statements that are controlled by a conditional expression. Here’s the syntax for the while
statement:
while expression: statement(s)
A while
statement can also include an else
clause, covered in The else Clause on Loop Statements, and break
and continue
statements, covered in The break Statement and The continue Statement.
Here’s a typical while
statement:
count = 0 while x > 0: x = x // 2 # truncating division count += 1 print "The approximate log2 is", count
First, Python evaluates expression
, which is known as the loop condition. If the condition is false, the while
statement ends. If the loop condition is satisfied, the statement or statements that make up the loop body execute. When the loop body finishes executing, Python evaluates the loop condition again to check whether another iteration should execute. This process continues until the loop condition is false, at which point the while
statement ends.
The loop body should contain code that eventually makes the loop condition false; otherwise, the loop will never end (unless an exception is raised or the loop body executes a break
statement). A loop that is in a function’s body also ends if a return
statement executes in the loop body, since the whole function ends in this case.
The for
statement in Python supports repeated execution of a statement, or block of statements, controlled by an iterable expression. Here’s the syntax for the for
statement:
for target in iterable: statement(s)
The in
keyword is part of the syntax of the for
statement and is distinct from the in
operator, which tests membership. A for
statement can also include an else
clause, covered in The else Clause on Loop Statements, and break
and continue
statements, covered in The break Statement and The continue Statement.
Here’s a typical for
statement:
for letter in "ciao": print "give me a", letter, "..."
iterable
may be any Python expression suitable as an argument to built-in function iter
, which returns an iterator object (explained in detail in the next section). In particular, any sequence is iterable. target
is normally an identifier that names the control variable of the loop; the for
statement successively rebinds this variable to each item of the iterator, in order. The statement or statements that make up the loop body execute once for each item in iterable
(unless the loop ends because an exception is raised or a break
or return
statement executes). Note that, since the loop body may contain a break
statement to terminate the loop, this is one case in which you may want to use an unbounded iterable—one that, per se, would never cease yielding items.
You can also have a target with multiple identifiers, as with an unpacking assignment. In this case, the iterator’s items must then be iterables, each with exactly as many items as there are identifiers in the target. For example, when d
is a dictionary, this is a typical way to loop on the items (key/value pairs) in d
:
for key, value in d.items( ): if not key or not value: # keep only true keys and values del d[key]
The items
method returns a list of key/value pairs, so we can use a for
loop with two identifiers in the target to unpack each item into key
and value
.
When an iterator has a mutable underlying object, you must not alter that object during a for
loop on it. For example, the previous example cannot use iteritems
instead of items
. iteritems
returns an iterator whose underlying object is d
, so the loop body cannot mutate d
(by executing del d[key]
). items
returns a list so that d
is not the underlying object of the iterator; therefore, the loop body can mutate d
. Specifically:
When looping on a list, do not insert, append, or delete items (rebinding an item at an existing index is OK).
When looping on a dictionary, do not add or delete items (rebinding the value for an existing key is OK).
When looping on a set, do not add or delete items (no alteration is permitted).
The control variable may be rebound in the loop body but is rebound again to the next item in the iterator at the next iteration of the loop. The loop body does not execute at all if the iterator yields no items. In this case, the control variable is not bound or rebound in any way by the for
statement. If the iterator yields at least one item, however, when the loop statement terminates, the control variable remains bound to the last value to which the loop statement has bound it. The following code is therefore correct, as long as someseq
is not empty:
for x in someseq: process(x) print "Last item processed was", x
An iterator is an object i
such that you can call i
.next( )
with no arguments. i
.next( )
returns the next item of iterator i
or, when iterator i
has no more items, raises a StopIteration
exception. When you write a class (see Classes and Instances), you can allow instances of the class to be iterators by defining such a method next
. Most iterators are built by implicit or explicit calls to built-in function iter
, covered in iter
in Built-in Functions. Calling a generator also returns an iterator, as we’ll discuss in Generators.
The for
statement implicitly calls iter
to get an iterator. The following statement:
for x in c:
statement(s)
is exactly equivalent to:
_temporary_iterator = iter(c)
while True:
try: x = _temporary_iterator.next( )
except StopIteration: break
statement(s)
where _temporary_iterator
is some arbitrary name that is not used elsewhere in the current scope.
Thus, if iter(
c
)
returns an iterator i
such that i
.next( )
never raises StopIteration
(an unbounded iterator), the loop for
x
in
c
never terminates (unless the statements in the loop body include suitable break
or return
statements, or raise or propagate exceptions). iter(
c
)
, in turn, calls special method c
._ _iter_ _( )
to obtain and return an iterator on c
. I’ll talk more about the special method _ _iter_ _
in _ _iter_ _
in Container methods.
Many of the best ways to build and manipulate iterators are found in standard library module itertools
, covered in The itertools Module.
Looping over a sequence of integers is a common task, so Python provides built-in functions range
and xrange
to generate and return integer sequences. The simplest way to loop n
times in Python is:
for i in xrange(n): statement(s)
range(
x
)
returns a list whose items are consecutive integers from 0
(included) up to x
(excluded). range(
x
,
y
)
returns a list whose items are consecutive integers from x
(included) up to y
(excluded). The result is the empty list if x
is greater than or equal to y
. range(
x
,
y
,
step
)
returns a list of integers from x
(included) up to y
(excluded), such that the difference between each two adjacent items in the list is step
. If step
is less than 0
, range
counts down from x
to y
. range
returns the empty list when x
is greater than or equal to y
and step
is greater than 0
, or when x
is less than or equal to y
and step
is less than 0
. When step
equals 0
, range
raises an exception.
While range
returns a normal list object, usable for all purposes, xrange
returns a special-purpose object, specifically intended for use in iterations like the for
statement shown previously (unfortunately, to keep backward compatibility with old versions of Python, xrange
does not return an iterator, as would be natural in today’s Python; however, you can easily obtain such an iterator, if you need one, by calling iter(xrange(...))
). The special-purpose object xrange
returns consumes less memory (for wide ranges, much less memory) than the list object range
returns, but the overhead of looping on the special-purpose object is slightly higher than that of looping on a list. Apart from performance and memory consumption issues, you can use range
wherever you could use xrange
, but not vice versa. For example:
>>> print range(1, 5) [1, 2, 3, 4] >>> print xrange(1, 5) xrange(1, 5)
Here, range
returns a perfectly ordinary list, which displays quite normally, but xrange
returns a special-purpose object, which displays in its own special way.
A common use of a for
loop is to inspect each item in an iterable and build a new list by appending the results of an expression computed on some or all of the items. The expression form known as a list comprehension lets you code this common idiom concisely and directly. Since a list comprehension is an expression (rather than a block of statements), you can use it wherever you need an expression (e.g., as an argument in a function call, in a return
statement, or as a subexpression for some other expression).
A list comprehension has the following syntax:
[ expression for target in iterable lc-clauses ]
target
and iterable
are the same as in a regular for
statement. You must enclose the expression
in parentheses if it indicates a tuple.
lc-clauses
is a series of zero or more clauses, each with one of the following forms:
for target in iterable if expression
target
and iterable
in each for
clause of a list comprehension have the same syntax and meaning as those in a regular for
statement, and the expression
in each if
clause of a list comprehension has the same syntax and meaning as the expression
in a regular if
statement.
A list comprehension is equivalent to a for
loop that builds the same list by repeated calls to the resulting list’s append
method. For example (assigning the list comprehension result to a variable for clarity):
result1 = [x+1 for x in some_sequence]
is the same as the for
loop:
result2 = [] for x in some_sequence: result2.append(x+1)
Here’s a list comprehension that uses an if
clause:
result3 = [x+1 for x in some_sequence if x>23]
This list comprehension is the same as a for
loop that contains an if
statement:
result4 = [] for x in some_sequence: if x>23: result4.append(x+1)
And here’s a list comprehension that uses a for
clause:
result5 = [x+y for x in alist for y in another]
This is the same as a for
loop with another for
loop nested inside:
result6 = [] for x in alist: for y in another: result6.append(x+y)
As these examples show, the order of for
and if
in a list comprehension is the same as in the equivalent loop, but in the list comprehension, the nesting remains implicit.
The break
statement is allowed only inside a loop body. When break
executes, the loop terminates. If a loop is nested inside other loops, a break
in it terminates only the innermost nested loop. In practical use, a break
statement is usually inside some clause of an if
statement in the loop body so that break
executes conditionally.
One common use of break
is in the implementation of a loop that decides whether it should keep looping only in the middle of each loop iteration:
while True: # this loop can never terminate naturally x = get_next( ) y = preprocess(x) if not keep_looping(x, y): break process(x, y)
The continue
statement is allowed only inside a loop body. When continue
executes, the current iteration of the loop body terminates, and execution continues with the next iteration of the loop. In practical use, a continue
statement is usually inside some clause of an if
statement in the loop body so that continue
executes conditionally.
Sometimes, a continue
statement can take the place of nested if
statements within a loop. For example:
for x in some_container: if not seems_ok(x): continue lowbound, highbound = bounds_to_test( ) if x<lowbound or x>=highbound: continue if final_check(x): do_processing(x)
This equivalent code does conditional processing without continue
:
for x in some_container: if seems_ok(x): lowbound, highbound = bounds_to_test( ) if lowbound <= x < highbound: if final_check(x): do_processing(x)
Both versions function identically, so which one you use is a matter of personal preference and style.
while
and for
statements may optionally have a trailing else
clause. The statement or block under that else
executes when the loop terminates naturally (at the end of the for
iterator, or when the while
loop condition becomes false), but not when the loop terminates prematurely (via break
, return
, or an exception). When a loop contains one or more break
statements, you often need to check whether the loop terminates naturally or prematurely. You can use an else
clause on the loop for this purpose:
for x in some_container: if is_ok(x): break # item x is satisfactory, terminate loop else: print "Warning: no satisfactory item was found in container" x = None
The body of a Python compound statement cannot be empty; it must always contain at least one statement. You can use a pass
statement, which performs no action, as a placeholder when a statement is syntactically required but you have nothing to do. Here’s an example of using pass
in a conditional statement as a part of somewhat convoluted logic to test mutually exclusive conditions:
if condition1(x): process1(x) elif x>23 or condition2(x) and x<5: pass # nothing to be done in this case elif condition3(x): process3(x) else: process_default(x)
Note that, as the body of an otherwise empty def
or class
statement, you may use a docstring, covered in Docstrings; if you do write a docstring, then you do not need to also add a pass
statement, although you are still allowed to do so if you wish.
Python supports exception handling with the try
statement, which includes try
, except
, finally
, and else
clauses. A program can explicitly raise an exception with the raise
statement. As I discuss in detail in Exception Propagation, when an exception is raised, normal control flow of the program stops, and Python looks for a suitable exception handler.
In Python 2.5, a with
statement has been added as a more readable alternative to the try
/finally
statement. I discuss it in detail in The with Statement.
Get Python in a Nutshell, 2nd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.