# 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