02. Control flow

Computational methods

Author

Marco A. Alsina

Published

May 17, 2026

Learning objectives

  • Implement loops for repetitive tasks
  • Understand common iterators in Python
  • Use conditional statements to control program flow
  • Apply list comprehensions for concise and efficient code

Control flow structures

Control flow structures allow directing the execution of a program based on a set of conditions, either iterative or conditional. These structures are foundational for decision making by either conditional criteria (e.g., threshold values), or by repeating calculations until a certain condition is met (e.g., time steps or iterating over a sequence).

Control flow structures are identified in Python with the colon notation :, followed by an indented block of instructions inside the control structure.

Iterative structures

Iterative structures repeat or loop through a set of instructions during a determined number of steps. The body of instructions is referred to as the loop body, while each repeating step is referred to as an iteration.

For statement

A for statement allow to execute a block of instructions for each value in a collection. Python offers several iterators to construct loops with a for statement, including a list, tuple or a dictionary. Note that a variable is declared inside the for statement, and it is used to loop over the values in the collection.

# list assignment
names = ['John', 'Peter', 'Mark', 'Andrew']

# for loop inside a list
for name in names:
    print(name)
John
Peter
Mark
Andrew
Important

The variable declared in the for statement remains in memory once the loop is completed, and thus must be reassigned if a different value is later needed for the variable.

Common iterators

The range() function generates a memory efficient collection of integers to use in a for statement. This function returns a range iterator type that is open at the upper endpoint. If needed, a type cast to list can be used to unpack the sequence in the iterator:

# range assignment
vals = range(3)
print(vals, type(vals), len(vals))

# type casting to list
print(list(vals))

# iterating through the range
for val in vals:
    print(val)
range(0, 3) <class 'range'> 3
[0, 1, 2]
0
1
2
Note

Most iterators are constructed using specific classes, so a type cast to a container class such as list or tuple is needed to unpack the sequence.

A range iterator can be used to access the values in a list by indexing:

# list assignment
names = ['John', 'Peter', 'Mark', 'Andrew']
n     = len(names)

# iterating through the list by indexing
for i in range(n):
    print(i, names[i])
0 John
1 Peter
2 Mark
3 Andrew

Another efficient way to iterate over a collection is the enumerate() function, which returns the index and value for each object in the collection. The function returns an enumerate iterator type, so a type cast to list can be used to unpack the sequence:

# list assignment
names = ['John', 'Peter', 'Mark', 'Andrew']

# iterating through the list by enumerate
for i, name in enumerate(names):
    print(i, name)

# type casting to list
enum = enumerate(names)
print(type(enum))
print(list(enum))
0 John
1 Peter
2 Mark
3 Andrew
<class 'enumerate'>
[(0, 'John'), (1, 'Peter'), (2, 'Mark'), (3, 'Andrew')]

In some instances we need to loop through several sequences in parallel. An efficient way to achieve the latter is to use the zip() function, which returns a tuple with the mapped values in each sequence. Similarly than before, the function returns a zip iterator type, so a type cast to tuple can be used to unpack the sequence:

# list assignment
names    = ['John', 'Peter', 'Mark', 'Andrew']
ages     = [32, 35, 28, 31]

for name, age in zip(names, ages):
    print(name, age)

# type casting to list
zipped = zip(names, ages)
print(type(zipped))
print(tuple(zipped))
John 32
Peter 35
Mark 28
Andrew 31
<class 'zip'>
(('John', 32), ('Peter', 35), ('Mark', 28), ('Andrew', 31))

We can also loop through the keys and values of a dictionary object with the method items(). The method returns a dict_items iterator type, so a type cast to list is used to unpack the sequence:

# dictionary assignment
kws = {'name': 'John', 'age': 32}

for key, val in kws.items():
    print(key, val)

# type casting
kws_items = kws.items()
print(type(kws_items))
print(list(kws_items))
name John
age 32
<class 'dict_items'>
[('name', 'John'), ('age', 32)]
Note

Additional classes for efficient iteration, including combinatorics, are implemented in the itertools library.

While statement

A while statement is a special type of iterative structure that executes a block of instructions while a given condition is True:

# variable assignment
counter = 0

# loop while n is lower than 5
while counter < 5:
    cond = (counter < 5)
    print('  Counter: %i (%s)'%(counter, cond))
    counter += 1

# exit value
cond = (counter < 5)
print('Counter: %i (%s)'%(counter, cond))
  Counter: 0 (True)
  Counter: 1 (True)
  Counter: 2 (True)
  Counter: 3 (True)
  Counter: 4 (True)
Counter: 5 (False)
Important

Note that the loop body needs to be updated manually, otherwise an infinite loop will occur!

Conditional structures

Conditional structures execute a set of instructions if a given condition is met. Python implement conditional structures through the if, else and elif statements.

If statement

An if statement executes a block of instructions if a given condition is True:

# variable assignment
temp = 10

# basic if statement
if temp > 5:
    print(f"{temp} is greater than 5")
10 is greater than 5

If else statement

An if statement can be followed by an optional else statement, which executes a block of instructions if the initial condition is False:

# variable assignment
temp = 5

# if else statement
if temp > 5:
    print(f"{temp} is greater than 5")
else:
    print(f"{temp} is equal or lower than 5")
5 is equal or lower than 5

If elif statement

Alternatively, an if statement can be followed with one or more conditions that are verified sequentially through elif statements, which is an abbreviation of else if. This set of statements can be closed with an else statement, which is executed if all previous conditions are False:

# variable assignment
temp = 22

# if elif else statement
if temp > 30:
    print('Hot')
elif temp > 20:
    print('Warm')
elif temp > 15:
    print('Mild')
else:
    print('Cold')
Warm

if statements can also be constructed with logical conditions:

# variable assignment
a = -8 ; b = 2

# logical conditions
if (a > b) and (a - b >= 10):
    print('a is much greater than b')
elif (b > a) and (b - a >= 10):
    print('b is much greater than a')
elif (a > b):
    print('a is greater than b')
elif (b > a):
    print('b is greater than a')
else:
    print('a is equal to b')
b is much greater than a

Control flow commands

Control flow commands allow to modify the execution of block of instructions inside iterative structures:

  • break: ends the current loop.
  • continue: proceeds with the next iteration.
  • pass: position marker to avoid error when no action is required.
# nested structure
for i in range(5):
    if i < 3:
        continue
    elif i == 3:
        pass
    else:
        break
print(i)
4

List comprehensions

Python offers list comprehension, which is a compact and efficient way to create lists based on a iterative control structure. The basic syntax is as follows: \[ [\text{instruction}\,for\,\text{item}\,in\,\text{iterator}] \]

# iterator assignment
nums    = range(8)

# squares
squares = [i**2 for i in nums]
print(squares)
[0, 1, 4, 9, 16, 25, 36, 49]
Important

The variable declared in the for statement inside a list comprehension is local, so it doesn’t remain in memory –or affects a global variable with the same name– once the loop is completed.

List comprehension is very useful to create new lists based on a given operation in a previous list:

# celsius to fahrenheit
celsius = [0, 10, 20, 30]
fahren  = [(1.8*c + 32) for c in celsius]

# printing results
for c, f in zip(celsius,fahren):
    print(f"{c} °C -> {f} °F")
0 °C -> 32.0 °F
10 °C -> 50.0 °F
20 °C -> 68.0 °F
30 °C -> 86.0 °F

The iterative structure of a list comprehension also accepts conditional arguments, which can be used to filter an original sequence:

# even numbers
evens   = [i for i in nums if (i % 2 == 0)]
print('Even numbers: ', evens)

# odd numbers
odds    = [i for i in nums if (i % 2 != 0)]
print('Odd numbers : ', odds)
Even numbers:  [0, 2, 4, 6]
Odd numbers :  [1, 3, 5, 7]

A list comprehension also accepts nested iterations through multiple for statements:

# paired numbers
paired = [(i,j) for i in evens for j in odds if (i < 4) & (j < 5)]
print('Paired numbers : ', paired)

# flattened list
flat = [num for val in paired for num in val]
print('Flattened pairs: ', flat)
Paired numbers :  [(0, 1), (0, 3), (2, 1), (2, 3)]
Flattened pairs:  [0, 1, 0, 3, 2, 1, 2, 3]

Exercises

  1. Declare the following variables:
nums  = range(1,11)
temps = [11, 27, 8, 35, 19, 5, 22]
  1. Use a for loop to print each value in nums.
  2. Use a for loop with enumerate() to print the index and value of each element in temps.
  3. Use a while loop to print all values in range that are lower than 6.
  4. Use a for loop with a continue statement to print only the odd values in nums.
  5. Use a for loop with a break statement to stop iteration when a temperature in temps exceeds 30, printing each index and value until the loop stops.
  6. Construct a list classified containing the label 'even' or 'odd' for each element in nums using list comprehension with a conditional.
  7. Compute the cumulative sum of nums using a for loop, storing each intermediate result in a list cumsum.
  8. Write an if/elif/else statement that classifies a temperature value as 'Cold' (below 10), 'Mild' (between 10 and 25), or 'Hot' (above 25).
  9. Use the code written in the previous exercise inside a for loop to create a list with the temperature classification ('Cold', 'Mild', or 'Hot') for each value in temps.
  10. Use zip() and list comprehension to create a list of tuples pairing each temperature in temps with its classification from the previous exercise.

Additional resources