Iterations
Last updated on 2024-05-23 | Edit this page
Download Chapter notebook (ipynb)
Mandatory Lesson Feedback Survey
Overview
Questions
- What do we mean by iterations and loops?
- How are
for
-loops implemented? - Can conditional statements be used in iterations?
- When to use
while
-loops?
Objectives
- Understanding the concept of iterations and loops.
- Learning the processes involved in
for
-loops implementation. - Building concept of using conditional statements in loops.
- Understanding when to use while loop.
This chapter assumes that you are familiar with the following
concepts in Python 3:
Additionally, make sure that you are comfortable with the principles of indexing in arrays before you start this section. It is very important that you have a good understanding of arrays and sequences, because the concept of iteration in programming deals almost exclusively with these subjects.
Note
You can practice everything in this section and the subsequent ones as you have been doing so far. However, if you find it hard to grasp some of the concepts, don’t worry, you are not alone. It takes practice. To help you with that, Philip Guo from UC San Diego (Calif., USA) has developed PythonTutor.com, an excellent online tool for learning Python. On that website, write (or ‘copy and paste’) your code in the editor, then click Visualize Execution. In the new page, use the forward and back buttons to see a step-by-step graphical visualisation of the processes that occur during the execution of your code. Try it on the examples in this section.
The concept
We employ iterations and loops in programming to perform repetitive operations. A repetitive operation is a reference to one or several defined operations that are repeated multiple times.
For instance, suppose we have a list
of 5 numbers as
follows:
numbers = [-3, -2, 5, 0, 12]
Now we would like to multiply each number by 2. Based on what we have learned thus far, this is how we would approach this problem:
PYTHON
numbers = [-3, -2, 5, 0, 12]
numbers[0] *= 2
numbers[1] *= 2
numbers[2] *= 2
numbers[3] *= 2
numbers[4] *= 2
print(numbers)
OUTPUT
[-6, -4, 10, 0, 24]
Whilst this does the job, it is clearly very tedious and repetitive. In addition to that, if we have an array of several thousand members, this approach becomes infeasible.
The process of multiplying individual members of our array with 2 is a very simple example of a repetitive operations.
Remember
In programming, there is a universally appreciated golden principle known as the DRY rule; and this is what it stand for:
Don’t Repeat Yourself
So if you find yourself doing something again and again, it is fair to assume that there might a better way of getting the results you’re looking for …
Some programmers (with questionable motives) have come up with a WET rule too. Find out more about DRY and WET from Wikipedia.
There are some universal tools for iterations that exist in all programming languages — e.g. for and while loops. Some other tools such as vectorisation or generators, however, are unique to one or several specific programming languages.
Throughout this section, we will discuss iterations via for and while loops, and review some real-world examples that may only be addressed using iterative processes.
for-loops
Some of the data show that up to 80% of all conventional iterations are implemented as for loops. Whether or not it is the best choice in of all these cases is a matter of opinion. What is important, however, is to learn the difference between the 2 methods and feel comfortable with how they work.
Implementation of for loops in Python is simple compared to other programming languages. It essentially iterates through an existing iterable variable — e.g. an array, and retrieves the values from it one by one, from the beginning right down to the end.
Remember
In Python, iterable is a term used in reference to variables that can be iterated through. Any variable type that can be used in a for loop without any modifications is therefore considered an iterable.
Most arrays and sequences are iterable. See Table to find out which
native types in Python are iterable. A rule of thumb is that if an array
or a sequence is numerically indexed (e.g. list
,
tuple
, or str
), it is an iterable.
Figure illustrates a flowchart to visualise the workflow of an iterative process using for loops in Python. The process depicted in the flowchart may be described as follows:
Advanced Topic
An iterable is a Python variable that contains the built–in method
.__iter__()
. Methods starting and ending with two
underscores (dunderscores) are also known as magic methods in
Python. See Python
documentations for additional information.
Process
A
for
-loop is initialised using an array or a sequence and begins its process by going through the array values from the first row.Iterative Process: The value of the current row is retrieved and given the alias item, which now represents a variable in the context of the loop.
-
Repetitive Operation(s): Designated operations are performed using the value of item:
- item *= 2
-
Loop Condition: The for loop automatically checks whether or not it has reached the last row of the sequence:
- NO: Move onto the next row and repeat the process from #2.
- YES: Exit the loop.
We write this process in Python as:
PYTHON
numbers = [3, 5, 6.3, 9, 15, 3.4]
for item in numbers:
item *= 2
# Display the item to see the results:
print(item)
OUTPUT
6
10
12.6
18
30
6.8
where we can see that the result for each iteration is displayed in a new line. Example outlines other such applications and expands on repetitive operations that may be simplified using for loops.
Remember
A for loop is always initialised as:
for variable_name in an_array:
# An indented block of processes
# we would like to perform on the
# members of our array one by one.
where an_array
is an iterable variable, and
variable_name
is the name of the variable we temporarily
assign to a member of an_array
that corresponds with the
current loop cycle (iteration). The number of loop cycles performed by a
for loop is equal to the length (number of members) of the
array that we are iterating through, which in this case is called
an_array
.
You can think of each iteration cycle as pulling out a row from table that is our array (as exemplified in section arrays) and temporarily assigning its corresponding value to a variable until the next iteration cycle.
See subsection List Members to find the length of an array.
PYTHON
for sequence in peptides:
length = len(sequence)
index = peptides.index(sequence)
print('Peptide', sequence, 'at index', index, 'contains', length, 'amino acids.')
OUTPUT
Peptide GYSAR at index 0 contains 5 amino acids.
Peptide HILNEKRILQAID at index 1 contains 13 amino acids.
Peptide DNSYLY at index 2 contains 6 amino acids.
Extended example of iterations using
for
loops
When using a for loop, we can also reference other variables that have already been defined outside of the loop block:
PYTHON
numbers = [3, 5, 6.3, 9, 15, 3.4]
counter = 0
for item in numbers:
item *= 2
# Display the item to see the results:
print('Iteration number', counter, ':', item)
counter += 1
OUTPUT
Iteration number 0 : 6
Iteration number 1 : 10
Iteration number 2 : 12.6
Iteration number 3 : 18
Iteration number 4 : 30
Iteration number 5 : 6.8
It is also possible to define new variables inside the loop, but remember that the value of any variables defined inside a loop is reset in each iteration cycle:
PYTHON
numbers = [3, 5, 6.3, 9, 15, 3.4]
counter = 0
for item in numbers:
new_value = item * 2
# Display the item to see the results:
print('Iteration number', counter, ':', item, '* 2 =', new_value)
counter += 1
OUTPUT
Iteration number 0 : 3 * 2 = 6
Iteration number 1 : 5 * 2 = 10
Iteration number 2 : 6.3 * 2 = 12.6
Iteration number 3 : 9 * 2 = 18
Iteration number 4 : 15 * 2 = 30
Iteration number 5 : 3.4 * 2 = 6.8
Retaining the new values
It is nice to be able to manipulate and display the values of an array but in the majority of cases, we need to retain the new values and use them later.
In such cases, we have two options:
- Create a new array to store our values.
- Replace the existing values with the new ones by overwriting them in the same array.
Creating a new array to store our values is very easy. All we need to do
is to create a new list
and add values to it in every
iteration. In other words, We start off by creating an empty
list
; to which we then add members using the
.append() method inside our for loop. The process
of creating a new list
and using the .append()
method to values to an existing list
are discussed in
subsections Useful
Methods and mutability,
respectively.
PYTHON
numbers = [-4, 0, 0.3, 5]
new_numbers = list()
for value in numbers:
squared = value ** 2
new_numbers.append(squared)
print('numbers:', numbers)
OUTPUT
numbers: [-4, 0, 0.3, 5]
OUTPUT
new_numbers: [16, 0, 0.09, 25]
The replacement method uses a slightly different approach. Essentially what we try to achieve is:
- read the value of an item in an array;
- manipulate the value via operations;
- put the value back to the original array through item assignment and thereby replace the existing value.
We learned about modifying an existing value in a list
in
subsection mutability, where we
discussed the concept of item assignment. The process of
replacing the original values of an array in a for loop is
identical. The key to performing this process, however, is that we need
to have the correct index for the specific member of the array
that we are trying to modify. Additionally, don’t forget that item
assignment is only possible in mutable arrays such as
list
. See Table to see which types
of array are mutable in Python.
To perform item assignment; we can implement a variable to represent the current iteration cycle in our for loop. We do so by initialising the variable with a value of 0, and adding 1 to its value at the end of each cycle. We can then use that variable as an index in each iteration cycle:
PYTHON
numbers = [-4, 0, 0.5, 5]
# Variable representing the
# index (iteration cycle):
index = 0
for value in numbers:
new_value = value ** 5
# Putting it back into
# the original array:
numbers[index] = new_value
# Adding one to the index for
# the next iteration cycle:
index += 1
print(numbers)
OUTPUT
[-1024, 0, 0.03125, 3125]
Advanced Topic
The enumerate()
function actually returns a
generator of tuple
items each time it is called in
the context of a for
loop. A generator is in principle very
similar to a normal array; however, unlike an array, the values of a
generator are not evaluated by the computer until the exact time at
which they are going to be used. This is an important technique in
functional programming known as lazy evaluation. It is
primarily utilised to reduce the workload on the computer (both the
processor and the memory) by preventing the execution of processes that
may be delayed for a later time. In the case of the
enumerate()
function, the values are evaluated at the
beginning of each iteration cycle in a for
loop. Learn more
about lazy evaluation in Wikipedia or
read more on generators in Python in the official
documentations.
This is a perfectly valid approach and it is used in many programming languages. However, Python makes this process even easier by introducing the function enumerate(). We often use this function at the initiation of a for loop. The function takes an array as an input and as the name suggests, enumerates them; thereby simplifying the indexing process. The previous example may therefore be written more concisely in Python as follows:
PYTHON
numbers = [-4, 0, 0.5, 5]
for index, value in enumerate(numbers):
# Manipulating the value:
new_value = value ** 5
numbers[index] = new_value
print(numbers)
OUTPUT
[-1024, 0, 0.03125, 3125]
for-loop and conditional statements
We can use conditional statements within for loops to account for and handle different situations.
Suppose we want to find the smallest value (the minimum) within a
list
of numbers using a for loop. The workflow
of this process is displayed as a flowchart diagram in figure below.
Given an array, we can break down the problem as follows:
Finally, we can implement the process displayed in figure as follows:
PYTHON
numbers = [7, 16, 0.3, 0, 15, -4, 5, 3, 15]
minimum = numbers[0]
for value in numbers:
if value < minimum:
minimum = value
print('The minimum value is:', minimum)
OUTPUT
The minimum value is: -4
Do it Yourself
Given:
PYTHON
peptides = [
'FAEKE',
'CDYSK',
'ATAMGNAPAKKDT',
'YSFQW',
'KRFGNLR',
'EKKVEAPF',
'GMGSFGRVML',
'YSFQMGSFGRW',
'YSFQMGSFGRW'
]
Using a for
loop and a conditional statement, find and
display the sequences in peptides that contain the amino
acid serine (S) in the
following format:
Found S in XXXXX.
Sequence of numbers in for-loops
To produce a sequence of int
numbers to use in a
for loop, we can use the built-in range()
function. The function takes in 3 positional arguments representing
start, stop, and step. Note that
range() is only capable of producing a sequence of
integer numbers.
Displaying the output of a range() function is not, as one might expect, an array of numbers:
OUTPUT
range(0, 10, 2)
It is, however, possible to evaluate the values outside of a
for loop. To do so, we need to convert the output of the
function to list
or a tuple
:
OUTPUT
[0, 2, 4, 6, 8]
Remember
The range() function is non-inclusive. That is, it
creates a sequence that starts from and includes the value given as the
start argument, up to but excluding the the value of the
end argument. For instance, range
(1, 5, 1) creates
a sequence starting from 1, which is then incremented
1 step at a time right up
to 5, resulting in a
sequence that includes the following numbers: 1, 2, 3, 4
while-loops
In the previous, we explored for
-loop mediated iterations
and learned that they are exclusively applied to iterable
objects — e.g. arrays and sequences. This is because, as demonstrated in
workflow figure, at the end of each iteration,
the implicit termination condition that is inherent in the
process tests whether or not it has reached the end of the sequence it
is iterating through.
It may, however, be deemed necessary to apply iterative processes based
on conditions other than that embedded in the for
-loop. In
such cases, we use a different class of iterations known as the
while
-loop.
Consider the following scenario:
We want to ask the user to enter a sequence of exactly 5 amino acids in single letter code. If the provided sequence is more or less than 5 letters long, we would like to display a message and ask them to try again; otherwise, we will display the process and terminate the programme.
It is impossible to write such a process using a for
-loop.
This is because when we initialise the iteration process, the number of
loops we need is unknown. In other words, we simply do not know how many
times the user would need enter said sequence before they get it right.
To simplify the understanding of the concept, we can visualise the process in flowchart, as displayed in figure. In the flowchart, you can see that the only way to exit the loop is to enter a sequence of exactly 5 characters. Doing anything else — i.e. entering a different number of letters – is tantamount to going back to be beginning of the loop. The process may be described verbally as follows:
Initialise the variable sequence and assign an empty string to it.
-
While the length of sequence is not equal to 5:
- Ask the use to enter a new sequence.
- Go back to #2.
Display the value of sequence.
Implementation
We start while
-loop using the while syntax,
immediately followed by the loop condition.
We can now implement the process displayed in figure as follows:
sequence = str()
while len(sequence) != 5:
sequence = input('Enter a sequence of exactly 5 amino acids: ')
print(sequence)
When executed, the above code will prompt the user to enter a value:
Enter a sequence of exactly 5 amino acids: GCGLLY
Enter a sequence of exactly 5 amino acids: GCGL
Enter a sequence of exactly 5 amino acids: GC
Enter a sequence of exactly 5 amino acids: GCGLL
GCGLL
As expected, the user is repetitively asked to enter a 5 character sequence until they supply the correct number of letters.
Do it Yourself
-
Write a script which asks the user to enter a number, then:
- if the second power of the number is smaller than 10, repeat the process and ask again;
- if the second power of the number is equal or greater than 10, display the original value and terminate the programme.
- We learned in subsection Sequence of Numbers that the built-in function range() may be utilised to produce a sequence of integer numbers. The function takes 3 input arguments in the following order: stop, start, step.
We now need a sequence of floating point numbers with the following criteria:
stop = 10
start = 0
step = 0.5
The use of a floating point number as step means that we cannot use
range() to create the desired sequence. Write a script in
which you use a while
-loop to produce a sequence of
floating point numbers with the above criteria and display the result.
The resulting sequence must be:
- presented as an instance of type
list
; - similar to range(), the sequence must be non-inclusive — i.e. it must include the value of start, but not that of stop.
value = 0
while value ** 2 < 10:
response = input('Enter a number: ')
value = float(response)
print(value)
Breaking a while-loop
Unlike for
-loops, it is common to break out of
a while
-loop mid-process. This is also known as
premature termination.
To consider a situation that may necessitate such an approach, we shall modify our scenario as follows:
We want to ask the user to enter a sequence of exactly 5 amino acids. If the sequence the user provides is more or less than 5 letters long, we would like to display a message and ask them to try again; otherwise, we will display the sequence and terminate the programme. Additionally, the loop should be terminated: - upon 3 failed attempts; or, - if the user entered the word exit instead of a 5 character sequence.
In the former case, however, we would also like to display a message and inform the user that we are terminating the programme because of 3 failed attempts.
To implement the first addition to our code, we will have to make the following alterations in our code:
Define a variable to hold the iteration cycle, then test its value at the beginning of each cycle to make sure that it is below the designated threshold. Otherwise, we manually terminate the loop using the break syntax.
Create a conjunctive conditional statement for the
while
-loop to make so that it is also sensitive to our exit keyword.
sequence = str()
counter = 1
max_counter = 3
exit_keyword = 'exit'
while len(sequence) != 5 and sequence != exit_keyword:
if counter == max_counter:
sequence = "Three failed attempt - I'm done."
break
sequence = input('Enter a sequence of exactly 5 amino acids or [exit]: ')
counter += 1
print(sequence)
Exercises
End of chapter Exercises
- Can you explain the reason why in the example given in subsection for-loop and conditional statements we set minimum to be equal to the first value of our array instead of, for instance zero or some other number?
Store your answer in a variable and display it using print().
- Write a script that using a for loop, calculates the sum of all numbers in an array defined as follows:
numbers = [0, -2.1, 1.5, 3]
and display the result as:
Sum of the numbers in the array is 2.4
- Given an array of integer values as:
numbers = [2, 1, 3]
write a script that using for loops, displays each number in the list as many time as the number itself. The programme must therefore display 2 twice, 1 once, and 3 three times.
- Given a
list
of numbers defined as:
numbers = [7, 16, 0.3, 0, 15, -4, 5, 3, 15]
write a script that using at most two for loops, finds the variance of the numbers, and display the mean, and the variance. Note that you will need to calculate the mean as a part of your calculations to find the variance.
The equation for calculating the variance is:
\[\sigma^2 = \frac{\sum^{n}_{i=1}(x_i - \mu)^2}{n}\]
Hint: Breaking down the problem into smaller pieces will simplify the process of translating it into code and thereby solving it:
Work out the Mean or \(\mu\) (the simple average of the numbers): \[ \mu = \frac{\sum^{n}_{i=1} x_i}{n}\]
Calculate the sum of: each number (\(x_i\)) subtracted by the Mean (\(\mu\)) and square the result.
Divide the resulting number by the length of number.
Display the results in the following format:
Mean: XXXX
Variance: XXXX
Q2
PYTHON
numbers = [0, -2.1, 1.5, 3]
numbers_sum = 0
for value in numbers:
numbers_sum += value
print("Sum of the numbers in the array is", numbers_sum)
OUTPUT
Sum of the numbers in the array is 2.4
Q3
PYTHON
numbers = [2, 1, 3]
for value in numbers:
prepped_value = [value] * value
for number in prepped_value:
print(number)
OUTPUT
2
2
1
3
3
3
Q4
PYTHON
numbers = [7, 16, 0.3, 0, 15, -4, 5, 3, 15]
numbers_length = len(numbers)
# Calculating the "sum"
# ---------------------------------------------------------
numbers_sum = 0
for value in numbers:
numbers_sum += value
# Calculating the "mean"
# ---------------------------------------------------------
numbers_mean = numbers_sum / numbers_length
# Calculating the "variance"
# ---------------------------------------------------------
variance_denominator = numbers_length
variance_numerator = 0
for value in numbers:
prepped_value = (value - numbers_mean) ** 2
variance_numerator += prepped_value
numbers_variance = variance_numerator / variance_denominator
# Results
# ---------------------------------------------------------
print("Mean:", numbers_mean)
print("Variance:", numbers_variance)
OUTPUT
Mean: 6.366666666666666
Variance: 48.919999999999995