Table Of Contents

Previous topic

Assignment operator

Next topic

Writing Functions

This Page

Download this page as:

Control Flow Statements

Setting and modifying variables will only get you so far before you need to use control flow statements such as if statements, or loops. This section describes a few of the most basic control flow statements that you will need to get started.

if statements

The basic syntax for an if-statement is the following:

if condition:
    # do something
elif condition:
    # do something else
else:
    # do yet something else

Notice that there is no statement to end the if statement. Notice also the presence of a colon (:) after each control flow statement. Python relies on indentation and colons to determine whether it is in a specific block of code. For example, in the following example:

In [1]: a = 5.

In [2]: if a == 1:
   ...:     print("a is 1, changing to 2")
   ...:     a = 2
   ...: print("finished")
   ...: 
finished

The first print statement, and the a = 2 statement only get executed if a is 1. On the other hand, print("finished") gets executed regardless, once Python exits the if statement.

Note

Indentation is very important in Python, and the convention is to use four spaces (not tabs) for each level of indent.

There are many degrees of freedom in typing Python code, especially in the amount of white space to surround loops, functions, assignments and function arguments, but also the naming of variables (using underscores, CamelCase...). To facilitate readability of the code to other developers, it is advised to adhere to some basic rules described in PEP 8.

Back to the if-statements: the conditions in the statements can be anything that returns a boolean value. For example, a == 1, b != 4, and c <= 5 are valid conditions because they return either True or False depending on whether the statements are true or not. Standard comparisons can be used (== for equal, != for not equal, <= for less or equal, >= for greater or equal, < for less than, and > for greater than), as well as logical operators (and, or, not). Parentheses can be used to isolate different parts of conditions, to make clear in what order the comparisons should be executed, for example:

if (a == 1 and b <= 3) or c > 3:
    # do something

More generally, any function or expression that ultimately returns True or False can be used.

Along with comparisons, another commonly-used operator is in. This is used to test whether an item is contained in any collection:

In [3]: b = [1, 2, 3]

In [4]: 2 in b
 Out[4]: True

In [5]: 5 in b
 Out[5]: False

If b is a dictionary, this tests that the item is a key of b.

Note

In the previous examples we have included comments. All lines starting with the # character are ignored by Python. If you would like to comment out a section of code, you can enclose it in triple quotes: '''commented out code'''.

for loops

The most common type of loop is the for loop. In its most basic form, it is straightforward:

for value in iterable:
    # do things

The iterable can be any Python object that can be iterated over. This includes lists, tuples, dictionaries, strings. Try the following in IPython:

In [6]: for x in [3, 1.2, 'a']:
   ...:     print(x)
   ...: 
3
1.2
a

Note that by putting the colon at the end of the first line, IPython automatically knows to indent the next line, so you don’t need to indent it yourself. After typing the print statement, you need to press enter twice to tell IPython you are finished writing code.

A common type of for loop is one where the value should go between two integers with a specific set size. To do this, we can use the range function. If given a single value, it will give a list ranging from 0 to the value minus 1:

In [7]: list(range(10))
 Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

If given two values, these will be the starting value, and one plus the ending value:

In [8]: list(range(3, 12))
 Out[8]: [3, 4, 5, 6, 7, 8, 9, 10, 11]

Finally, if a third number is specified, this is taken to be the step size:

In [9]: list(range(2, 20, 2))
 Out[9]: [2, 4, 6, 8, 10, 12, 14, 16, 18]

The range function should be used as the iterable in a for loop.

Exercise

Write a for loop that prints out the integers 1 to 9, but not 5 and 7.

Click to Show/Hide Solution

In [10]: for x in range(1, 10):
   ....:     if x != 5 and x != 7:
   ....:         print(x)
   ....: 
1
2
3
4
6
8
9

while loops

Python also provides a while loop which is similar to a for loop, but where the number of iterations is defined by a condition rather than an iterator:

while condition:
    # do something

For example, in the following example:

In [11]: a = 0

In [12]: while a < 10:
   ....:      print(a)
   ....:      a += 1
   ....: 
0
1
2
3
4
5
6
7
8
9

the loop is executed until a is equal to or exceeds 10.

Exercise

Write a while loop to print out the Fibonacci numbers below 100.

Click to Show/Hide Solution

In [13]: a = 0

In [14]: b = 1

In [15]: while a < 100:
   ....:      print(a)
   ....:      c = a + b
   ....:      a = b
   ....:      b = c
   ....: 
0
1
1
2
3
5
8
13
21
34
55
89

More advanced features

break out of enclosing for/while loop:

In [16]: z = 1 + 1j

In [17]: while abs(z) < 100:
   ....:      print(z,abs(z))
   ....:      if z.imag < 0:
   ....:          break
   ....:      z = z**2 + 1
   ....: 
((1+1j), 1.4142135623730951)
((1+2j), 2.23606797749979)
((-2+4j), 4.47213595499958)
((-11-16j), 19.4164878389476)

continue the next iteration of a loop:

In [18]: a = [1, 0, 2, 4]

In [19]: for element in a:
   ....:      if element == 0:
   ....:          continue
   ....:      print(1. / element)
   ....: 
1.0
0.5
0.25

Iteration tools

Common task is to iterate over a sequence while keeping track of the item number.

  • Could use while loop with a counter as above. Or a for loop:

    In [20]: words = ('cool', 'powerful', 'readable')
    
    In [21]: for i in range(0, len(words)):
       ....:      print(i, words[i])
       ....: 
    (0, 'cool')
    (1, 'powerful')
    (2, 'readable')
    
  • But Python provides enumerate for this:

    In [22]: for index, item in enumerate(words):
       ....:      print(index, item)
       ....: 
    (0, 'cool')
    (1, 'powerful')
    (2, 'readable')
    
  • Similarly, it is possible to zip two (or more) things simultaneously:

    In [23]: fruits = ('apple', 'orange')
    
    In [24]: for word, fruit in zip(words, fruits):
       ....:      print(word, fruit)
       ....: 
    ('cool', 'apple')
    ('powerful', 'orange')
    
  • Many more tools exist as part of the itertools package. In particular the itertools.product function can come in handy to avoid nested for loops, allowing a cleaner and commonly slightly faster implementation.

List Comprehensions

A common programming structure when assigning values to a list is the following:

In [25]: l = []                      # create the list

In [26]: for i in range(10):
   ....:     l.append(i**2)
   ....: 

In [27]: l
Out[27]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

List comprehensions provide a shorter and more readable way of writing the same loop:

In [28]: l = [i**2 for i in range(10)]

In [29]: l
Out[29]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

But they are more powerfull than this. You can make conditional list comprehension, e.g. to filter out the even numbers and multiples of 7:

In [30]: print([i for i in range(20) if (i%2!=0) and (i%7!=0)])
[1, 3, 5, 9, 11, 13, 15, 17, 19]

Or you can put all those elements to zero, if you put the condition statement inside the loop:

In [31]: print([(i if ((i%2!=0) and (i%7!=0)) else 0) for i in range(20)])
[0, 1, 0, 3, 0, 5, 0, 0, 0, 9, 0, 11, 0, 13, 0, 15, 0, 17, 0, 19]

List comprehensions are a very powerful tool, but can severly obfuscate your code. Consider expanding them as normal for loops if the speed gain is not vital and clarity is important.

Copyright: Smithsonian Astrophysical Observatory under terms of CC Attribution 3.0 Creative Commons
 License