Control Structures#

What you will learn in this lesson:

  • Conditional statements (if, elif, else)

  • Loops (for, while)

  • Break and continue statements

  • Some built-in functions useful to work with loops

Introduction#

Python includes structures to control the flow of a program:

  • conditions (if, else)

  • loops

    • while-loop
      Execute statements while a condition is true

    • for-loop
      Iterates over a iterable object (list, tuple, dict, set, string)

Indentation#

Here things start to get interesting in a good way.

To define control structures (and functional blocks of code in general), Python uses uses tabs – spaces, actually –. This is in contrast to most languages that use either characters like braces { and } (e.g. R, C, C++) or key words like IF ... END IF (e.g. Matlab, Fortran, Bash).

It is therefore imperative to understand and become familiar with indentation.

Conditions#

if and else can be used for conditional processing.#

if conditon:
    expression

val = -2

if val >=0:
    print(val)
else:
    print(-val)
2

using if, elif#

elif is reached when the previous statements are not.

val = -2

if -10 < val < -5:
    print('bucket 1')
if -5 <= val < -2:
    print('bucket 2')
elif val == -2:
    print('bucket 3')
bucket 3

using if, elif, else#

else can be used as a catchall

val = 5

if -10 < val < -5:
    print('bucket 1')
elif -5 <= val < -2:
    print('bucket 2')
elif val == -2:
    print('bucket 3')
else:
    print('bucket 4')
bucket 4

writing if and else as one-liners#

x = 3
print('odd') if x % 2 == 1 else print('even')
odd

Notice == for checking the condition x % 2 == 1.

both if and else are required. this breaks:

print('odd') if x % 2 == 1
  Cell In[5], line 1
    print('odd') if x % 2 == 1
    ^
SyntaxError: expected 'else' after 'if' expression

Using multiple conditions#

Can build complex statements. Use parentheses carefully, to keep order of operations correct.

val = 2

if (-2 < val < 2) or (val > 10):
    print('bucket 1')
else:
    print('bucket 2')
bucket 2

Let’s have a look at the following example… Could anybody tell why the obtained result?

val = 2

if (-2 < val) < 2 or val > 10:
    print('bucket 1')
else:
    print('bucket 2')
bucket 1

Loops#

while-loop#

while condition :
    expression

  • Numerically calculating model

  • ‘repeating action until condition is met’

What does this print?

ix = 1
while ix < 10:
    ix = ix * 2
print(ix)
16

break - exit the loop#

sometimes you want to quit the loop early, if some condition is met.
uses if-statement

ix = 1
while ix < 10:
    ix = ix * 2
    if ix == 4:
        break
print(ix)
4

The break makes the loop end early.

continue - stop the current iteration#

sometimes you want to introduce skipping behavior in the loop.
uses if-statement

ix = 1
while ix < 10:
    ix = ix * 2
    if ix == 4:
        print('skipping 4...')
        continue
    print(ix)
2
skipping 4...
8
16

The continue causes the loop to skip printing 4.

for loop#

for var in iterable :
    expression

  • ‘for each var in seq, execute the expression’

  • iterate over an iterable

Important: An iterable can be a string or any of the data structures (i.e. lists, ranges, dictionaries...) studied earlier.
cities = ["Bilbao", "Valencia", "Bari", "Cville", "PITT"]

# See how we loop through this list
for city in cities:
    city = city.lower()
    print(city)
bilbao
valencia
bari
cville
pitt

quit early if Bari reached, using break

cities = ["Bilbao", "Valencia", "Bari", "Cville", "PITT"]

for city in cities:
    if city == 'Bari':
        break
    city = city.lower()
    print(city)
bilbao
valencia

skip over Bari if reached, using continue

cities = ["Bilbao", "Valencia", "Bari", "Cville", "PITT"]

for city in cities:
    if city == 'Bari':
        continue
    city = city.lower()
    print(city)
bilbao
valencia
cville
pitt

Now let’s loop through a dictionary, searchin by its key

things = {"apples": 1, "bananas": 2, "grapes": 3, "mangos": 4, "blueberries": 5, "kumquats": 6, "kiwis": 7}
lookfor = "kumquats"

for t in things.keys():
    if (t == lookfor):
        # Do something
        print("I found some " + lookfor + ". It has a value of " + str(things[t]))
    else:
        print("Nothing here")
        pass
Nothing here
Nothing here
Nothing here
Nothing here
Nothing here
I found some kumquats. It has a value of 6
Nothing here

Here looping throuhg a tuple:

this_tuple = ("apple", "banana", "cherry")
for i in this_tuple:
  print(i)
apple
banana
cherry
Beware: If you iterate over an unordered data structure (e.g. sets), python will impose an arbitrary order.
# This may be different to using tuples
this_set = {"apple", "banana", "cherry"}
for j in this_set:
  print(j)
cherry
banana
apple
WHILE vs FOR
  • For loops are used to loop through a list of values or an operation in which the number of iterations is known in advance.

  • While loops are when you don’t know how many interations it will take – you are depending on some condition to be met.

DANGER: Be careful with while loops, as they might be unending. For example:
    
while 1:
    print("This is so annoying")

Some useful built-in functions with loops#

The following are a couple of super useful functions I personally use with loops almost every day.

zip()#

So far we have been looping through single list with values… But what if you have several lists, and want to iterate over them in parallel? zip can do this for you:

cities = ["Bilbao", "Valencia", "Bari", "Cville", "PITT"]
countries = ["Spain", "Spain", "Italy", "USA", "USA"]

for city, country in zip(cities, countries):
    print(f"{city} belongs to {country}")
Bilbao belongs to Spain
Valencia belongs to Spain
Bari belongs to Italy
Cville belongs to USA
PITT belongs to USA
# zip produces tuples with an item from each list.
list(zip(cities, countries))
[('Bilbao', 'Spain'),
 ('Valencia', 'Spain'),
 ('Bari', 'Italy'),
 ('Cville', 'USA'),
 ('PITT', 'USA')]

enumerate()#

This is another useful function when we want to keep track of the index in each element of the list we are iterating over. Maybe you can’t see right now the utility of this, but believe me, there is!

for index, city in enumerate(cities):
    print(f"{city} has index {index}")
Bilbao has index 0
Valencia has index 1
Bari has index 2
Cville has index 3
PITT has index 4
# Change Cville to Charlottesville by accessing its index
for index, city in enumerate(cities):
    if city == "Cville":
        cities[index] = "Charlottesville"
        
cities
['Bilbao', 'Valencia', 'Bari', 'Charlottesville', 'PITT']
# You can even combine enumerate and zip
for index, (city, country) in enumerate(zip(cities, countries)):
    print(f"{city} belongs to {country}. Both elements are in the {index} position in their list")
Bilbao belongs to Spain. Both elements are in the 0 position in their list
Valencia belongs to Spain. Both elements are in the 1 position in their list
Bari belongs to Italy. Both elements are in the 2 position in their list
Charlottesville belongs to USA. Both elements are in the 3 position in their list
PITT belongs to USA. Both elements are in the 4 position in their list
# Look at the parenthesis above. First it goes enumerate, and then zip.
for index, city, country in enumerate(zip(cities, countries)):
    print(f"{city} belongs to {country}. Both elements are in the {index} position in their list")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[33], line 2
      1 # Look at the parenthesis above. First it goes enumerate, and then zip.
----> 2 for index, city, country in enumerate(zip(cities, countries)):
      3     print(f"{city} belongs to {country}. Both elements are in the {index} position in their list")

ValueError: not enough values to unpack (expected 3, got 2)

Practice exercises#

Exercise 16

1 - Given z=4 write an “if” statement that evaluates if z is odd or even and then print z is even.
2 - Add an “else” statement to the previous code to print “z is odd”. Try changing the value of z to see whether your code works or not.
3 - Inside either the “if” or “else”, include a print statement giving the message of what number is being checked by the condition. (Hint: use string formatting for this).

# Your answers here

Exercise 17

Write code that does the following:

1 - Define a list of integers xx = [-2, 8, 0, 5, 6]
2 - Compute the maximum value of the list, storing it in a variable named “max_val”. (Hint: You may use the built-in function max for this).
3 - Now, loop over each value in the list such that, if the value is less than the maximum, it prints the value; otherwise, it prints ‘max_val’.

# Your answers here

Exercise 18

Write a while loop to print the numbers from 1 to 10. However, if the number being printed is 7, the loop should stop early using a break statement.

# Your answers here