Conditionals

Indices and tables

Python supports the common set of conditional expressions that you will find in other languages, but enhanced slightly with some useful features.

if Statement

The syntax for the if statement, shown below, is similar to other languages. There can be zero or more elif clauses and zero or one else clauses. The branch is taken if the expression evaluates to True.

if_stmt ::=  “if” expression “:”
                 suite
             “elif” expression “:”
                 suite
             “else” “:”
                 suite

For example:

if tigers_present:
    print("Running away!")
elif swimming_pool_present:
    print("Chillin...")
else:
    print("Looking for anything")

Some simple cases can be boiled down to a conditional expression:

cond_expr ::=  expression1 "if" expression2 "else" expression3

For example:

status_string = "Running away!" if tigers_present else "Looking for tigers"

Tip

Recall the pass statement can be used in any branch that must be created but requires no action from the program. It is also useful to use pass to mark out areas for further work when stubbing out code so you can keep creating the outer structure without having to think of all the inner details.

case Statement

Python doesn’t have syntax for a case statement. There have been attempts to get it added (PEP 275 and PEP 3103) but they have failed.

The reality is, since if is cheap in Python, you can use, if and membership testing as an alternative to a case statement. For example:

if x in (0, 2, 4, 5):
   print("---")
elif x in (1, 56, 527):
   print("***")
elif x in (99, 404, 38):
   print("%%%")
else:
   print("~~~")

Another alternative is to create a dictionary and index the dictionary for the result. For example:

def fn0():
    print("Function0 called")

def fn1():
    print("Function1 called")

def do_work(val):

   # Use dict to construct artificial case statement
   # Keys - The values to switch off of
   # Vals - The functions that get called
   case = {0: fn0,
           1: fn1}

   # Index into the dict for function to call
   # and call it.
   case[val]()

do_work(0)

Tip

Remember, everything in Python is a an object. Functions are objects. Reference to function objects can be passed around by-name, just like references to other types of objects.

This is actually a bit of a heated topic. If interested, a good discussion on this can be found here.

while Loop

Python’s support for the while loop construct is similar to other languages. The while loop is executed as long as expression remains True.

The break (exit loop) and continue (go back to top of loop) statements are supported.

Python extends the while loop with the handy addition of an optional else clause.

while_stmnt ::=  "while" expression ":"
                    suite
                 "else" ":"
                    suite

The else clause is executed when the loop terminates normally (i.e. expression is, or becomes, False), but not if the loop terminates abnormally (i.e. from using break, return or an exception is raised).

For example:

cntr = 0
cntr_max = 10

while cntr <= cntr_max:
    # Discard certain select values
    if cntr in (1, 5):
       cntr += 1
       continue
    # Process non-discarded values
    print(cntr)
    cntr += 1
else:
    # Print a completion message
    print("DONE")

Would produce the following (with 1 and 5 skipped):

0
2
3
4
6
7
8
9
10
DONE

for loop

Python’s support for the for loop construct is similar to other languages, except, in Python the for loop iterates over a sequence of items, not necessarily a progression of numbers.

The break (exit loop) and continue (go back to top of loop) statements are supported.

Like the while loop, the for loop is also extended with the optional else clause.

for_stmt ::=  "for" target_list "in" expression_list ":"
                  suite
              "else" ":"
                  suite

The else clause is executed when the loop terminates normally (i.e. the sequence of items is exhausted), but not if the loop terminates abnormally (i.e. from using break, return or an exception is raised).

For example:

>>> for val in "Hello World":
...     # Skip spaces
...     if val in " " : continue
...     # Print value with a trailing dash
...     print(val + "-", end='')
... else:
...     # Print closing message
...     print(":::😊")
...
H-e-l-l-o-W-o-r-l-d-:::😊

A for loop also allows you to have multiple loop variables. Each item in expression_list will be unpacked into the arguments in target_list. For example:

>>> items = enumerate(['a', 'b', 'c', 'd'])
>>> items = list(items)
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
>>>
>>> for idx,val in items:
...    print("Index: {}  Value: {}".format(idx, val))
...
Index: 0  Value: a
Index: 1  Value: b
Index: 2  Value: c
Index: 3  Value: d

Warning

A common mistake is to modify the sequence being iterated over. Instead, iterate over a copy of it and modify the original. An easy and fast way to get a shallow copy of a sequence is using [:]. For example:

>>> salaries = [60000, 75000, 105000]
>>> for idx,salary in enumerate(salaries[:]):
...     salaries[idx] = salary + 10000
>>> print(salaries)