Loops

Definition

Loops should be used when a set of actions must be repeated a certain number of times (for instance on each element of a list).

There is mainly two ways to perform a loop: by using a for statement, or by using a while statement.

Loops in Python

In Python, the general structure of a loop is:

for v in iterable:
    action

while(condition):
    action
You can always replace a for loop by a while loop, and conversely.

First, let’s create a list, which is an iterable

# creates a list
x = ['a', 'b', 'c', 'd', 'e']
x
['a', 'b', 'c', 'd', 'e']

You can loop over a list by using its index as follows:

# loop using the list index
for p in range(0, len(x)):
    print('iterable ', p, 'element', x[p])
iterable  0 element a
iterable  1 element b
iterable  2 element c
iterable  3 element d
iterable  4 element e

Here, the iteration is done on an integer (p), which is an integer.

But the iteration can also be performed on the elements themselves:

# loop using the list elements (works for iterables, such as list, tuples)
for v in x:
    print('iterable ', v)  # temp: element itself
iterable  a
iterable  b
iterable  c
iterable  d
iterable  e

Pairwise loops

There is the possiblity to loop simultaneously over different elements using the zip method, which returns a tuple of pairs.

x = ['a', 'b', 'c', 'd']
x
['a', 'b', 'c', 'd']
y = ['w', 'x', 'y', 'z']
y
['w', 'x', 'y', 'z']
list(zip(x, y))
[('a', 'w'), ('b', 'x'), ('c', 'y'), ('d', 'z')]
for i, j in zip(x, y):
    print(i, j)
a w
b x
c y
d z

The zip method method will stop when the end of one of the iterable has been reached.

z = ['alpha', 'beta']
for val in zip(x, y, z):
    print(val)
('a', 'w', 'alpha')
('b', 'x', 'beta')

Any for loop can be converted into a while loop, and conversely. For instance, to navigate on a list:

# any for loop can be converted into while loop, and conversely
x = ['a', 'b', 'c', 'd']


p = 0
while p < len(x):
    print('index ', p, 'value', x[p])  # p: index of the element
    p += 1 # iteration of counter
index  0 value a
index  1 value b
index  2 value c
index  3 value d

To navigate in a list starting by the end:

p = len(x) - 1
while (p >= 0):
    print('index ', p, 'value', x[p])  # p: index of the element
    p -= 1 # iteration of counter 
index  3 value d
index  2 value c
index  1 value b
index  0 value a

Imbricated loops

Imbricated loops are achieved by indenting the code as many times as necessary

for i in range(0, 2):
    for j in range(0, 3):
        for k in range(0, 1):
            print('i', i, 'j', j, 'k', k)
i 0 j 0 k 0
i 0 j 1 k 0
i 0 j 2 k 0
i 1 j 0 k 0
i 1 j 1 k 0
i 1 j 2 k 0

Loop comprehension

Python allows writting loops in a very synthetic way, which is called loop comprehension. For instance, the following loop:

# equivalent to (but much shorter and more elegant)
combs2 = [] 
for x in [1, 2, 3]:
    for y in [3, 1, 4]: 
        if x != y:
            combs2.append((x, y))
combs2
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

can be written as follows:

combs1 = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y] 
combs1
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

If you have 2 lists, x and y:

x = list(range(1, 10))
y = [3, 5, 6] 
list(x)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

If you want to extract the element of x which are not contained in y:

z = [a for a in x if a not in y] 
z
[1, 2, 4, 7, 8, 9]

Loop controls: break and continue

break allows to leave a loop when a condition is met:

# Break: leaves the loop when condition is met
for p in range(0, 10):
   
    print('===== ', p)
    
    if(p > 3):
        break
=====  0
=====  1
=====  2
=====  3
=====  4

On the other hand, continue does not leave the loop but the statements that come after are not reached.

# Continue: skip the end of the block when condition is met
for p in range(0, 10):

    print('++++++ ', p)

    if(p > 3):
        continue

    print('below')
++++++  0
below
++++++  1
below
++++++  2
below
++++++  3
below
++++++  4
++++++  5
++++++  6
++++++  7
++++++  8
++++++  9