By the end of this lesson, you should be able to:
for
statements.
for
statements.
for
loops.
range
function in for
statements.
for
or while
statements.
Repetition of a task is not something new for humans. For example, when we are preparing a mixture for a cake, we need to repeat tasks like putting three teaspoons of sugar in the mixture. Let’s analyze this task on an abstract level.
In this lesson we discuss Python repetition structures. There are two
types of repetition structures in Python, one is called for loops and
other is while loops. They cause a group of statements to be executed
repeatedly in a loop. Both for
and while
statements appear on most structural languages. However, Python has a
distinct way of using for
statements, which involves the
use of iterable objects. In this lesson, we introduce the for
statement.
The lesson starts by providing a holistic overview of the for
statement and introducing the concept of iterable objects. The second
section introduces the range function and presents different
methods for generating number sequences. Then we present a step-by-step
analysis of a problem that is solved using a for
statement.
These three sections provide what you essentially need to know about for
statements. The rest of the module involves advanced operations with for
statement. This involves the break
, continue
,
nested for loops and for else
.
for
Statement
Objects in Python appear in different forms and types. One method to classify objects is to divide them into two groups: iterable objects and non-iterable objects.
An iterable object is any object that allows you to pick its member items (elements) one by one. Think of it as a box that has a collection of items, for example small balls. This box has a hole to the side which when you click on the 'iterate' button it starts throwing the balls out of the box one by one until no more balls remain in the box. Any box that has this 'iterate' button could be described as an iterable box (object), and any box that does not have this feature is called non-iterable.
The concept of iterability is not associated with what you are doing with each item. It is only associated with the fact that you can access the elements one by one. In the ball box example, it does not matter if the balls are being shot out of the box, if you insert your hand into the box and pick one ball at a time, or if you simply look through the hole and take a picture of each ball one at a time. In all of these examples, you have the capacity to access the elements one after the other. This is what iterability is.
Python is distinguished with the concept of iterability. This concept is absent from some languages like C. Other languages like Java and C++ provide some mechanisms for iterating through collection objects. However, this comes in no way closer to how Python supports this concept. In Python, iterability is more natural and native to the language basics.
Python has several built-in data types which are iterable. This includes strings, lists, tuples, sets and dictionaries. A user could also define their own objects and support them with the feature of being iterable. At this stage, the iterable data type which you are most familiar with is strings. Therefore, in the following section, when we present the for-statement, strings are used as the primary example.
In strings, the iterability works on the characters of a string. For
example, the string ‘hello’
when iterated produces the
letters h, e, l, l, o
. Now for the number 629
,
we cannot iterate through the digits 6
, 2
and
9
, because an integer is not an iterable object in Python.
Iterable objects work closely with for
loops. We can say
that in Python the primary use of a for loop statement is to
iterate through iterable objects. This goes both ways, i.e. every for
statement uses an iterable object and every iterable object could be
used in a for statement.
The syntax of a Python for
statement is defined below:
for <var> in <iterable>:
<block of code>
You can read the above statement as the following: for every item in the iterable object, perform the following steps.
The for
term is the keyword for the loop command.
The <var>
is any variable name of your
choice. This variable is used to identify the element that you pick from
the iterable object at each iteration. The in
operator is a built-in Python operator that works only for iterable
objects which checks if an item is found inside a given collection
(iterable object). This operator is called the contains
operator. Similar to the if
and while
statements, the for statement ends with a colon and the enclosed block
is indented by the same level.
Let us take an example of iterating through a string using for loops.
Since the above example is too simple, let us look at another example to
enforce your understanding of how for
loops are used with
strings.
range
Function
In the previous section, you saw how strings could be iterated using a for
loop statement. However, it is not clear how a programmer would iterate
through a sequence of numbers. Since integers and floats are
non-iterable objects in Python, the for
statement cannot be
used directly with numbers. Python offers the function range
to achieve this task.
In this section, you will learn how to use the range
function within a for
loop statement to iterate through
numbers. This has several useful applications like counting and
generating mathematical sequences.
Technical Note:
In Python 2, a range is a function. However, in Python 3 it was changed to a data type. You can verify this by trying:
x = range(0,5)
print(type(x))
However, for the purposes of this course, it is easier to still think of a range as a function. In future courses, when you get more understanding of object oriented principles, you may revisit this concept to understand what it means for Python to deal with a range as a data type.
If a user is interested in generating a sequence of numbers between 0 to N, then the following syntax should be used:
for <var> in range(<N>):
<block of code>
The above syntax generates numbers from 0 up to, but not including, the number N. If a user is interested in 0 to N, inclusive both ends, then the for statement should be:
for <var> in range(<N+1>):
At each iteration, <var>
is updated with the next
number in the sequence. At the start of the loop <var>
is initialized to 0, and in the second iteration it gets the value of 1,
and so forth.
As we mentioned earlier, it is up to the user to decide what to do with the numbers. The user could simply print the number or pass it to some expression or function for some processing.
Let us have a look at an example.
Example 6.3.A:
Write a Python function called print_nums(n)
. The function
prints all numbers between 0
to n
, but not
including n
. The function prints each three numbers on a
separate line. In each line the numbers are separated with a tab
character.
Below is the solution:
# Program Name: Prog 6-03
# Solution to Example 6.3.A
def print_nums (n):
for i in range(n):
print("{}". format(i),end=’’)
if (i +1) % 3 == 0:
print()
else:
print(‘\t’, end=’’)
return
n = int(input("Enter value of n: "))
1 print_nums(n)
The lines of interest to this module are lines 5 to 10, so we analyze them:
Line 5 | The for loop generates a sequence of numbers from 0
to n (exclusive). At each iteration, the variable i
is used to refer to the generated number.
|
Line 6 | Prints the generated number. Observe how the print statement ends with an empty string. Therefore, nothing is printed after each number, not even a newline. |
Lines 7, 8 | The conditional statement prints a new line whenever three
numbers have been printed. Note how the term (i+1 ) is
used to avoid the problem of printing a newline when the value of i
is 0 .
|
Lines 9, 10 | The else statement prints a tab between numbers in the same line. |
Running the above program produces output similar to the following:
Enter value of n: 8
0 1 2
3 4 5
6 7
As you can see from the above example, using the range
function within a for
statement is quite simple. The
formatting part of when to print a new line or tab is not directly
relevant to the generation of numbers.
Technical Note:
When describing the range function, we have been using the term 'sequence of numbers'. This comes from the fact that the following code:
for i in range(0,4):
print(i)
is equivalent to:
for i in 0,1,2,3:
print(i)
However, there is a little trick here. The sequence 0,1,2,3 is not an actual sequence, because there is no data type in Python called sequence. It is a tuple. The concept of tuples will be covered in Lesson 12.
The basic range
structure presented above always generates
numbers starting from 0. But what if we would like to start from another
number?
This could be achieved with a simple change to the for loop statement:
for <var> in range(<M>,<N>):
<block of code>
The above loop will generate a sequence of numbers between M
(inclusive) up to N
(exclusive). Again, the naming of the
variables M
and N
is arbitrary, and we can
select any other name of our choice.
This little change in using the range function grants us more flexibility, as we can include negative numbers in our sequences. Let us look at an example.
After presenting the above two forms of the range function, it is time to present the general form:
for <var> in range(start,end,step):
<block of code>
The main addition here is the step
variable. The step
determines how the numbers in the sequence should be spaced out. In the
previous examples, the numbers were consecutive which means the step
was 1. If you want to generate numbers in alternating fashion, then the
step
should be 2, and so forth.
Let us look into a scenario where using steps in the range function would produce more efficient code. Suppose you want to print all multiples of 5 which are between 0 and 100, inclusive both ends. Based on what we learned in 6.3.2, this could be done using the following:
for i in range(0,101):
if i % 5 == 0:
print(i)
The above loop will undergo 101 iterations. However, we can reduce the number of iterations by doing the following:
for i in range(0,101,5):
print(i)
The above code will only undergo 21 iterations, which is about 20% of the previous number. Not only does this provide efficiency, but also simplicity as there is no need to introduce a conditional statement.
To ensure good understanding of the general form of the range function, you can practice with the following example:
By reaching this point in the lesson, you would have covered the basic
principles of the for
loop statement. What remains is only
tips and hints in addition to some advanced operations. What you need at
this stage is practice and more practice. We will offer in the following
section a detailed example of a slightly more complex problem that
requires the use of for
loops.
for
In this section, we will present a detailed problem which requires the
use of the for
statement. We will take you through the
thought process and show how a complicated problem could be simplified
through gradual progress.
Here is the problem.
Example 6.4:
Assume you have the following series: \(\sum_{i=0}^{n} (a+i)x^i\)
The series can be expanded as: \(a + (a+1)x + (a+2)x^2+ \cdots +(a+n)x^n \)
Write a Python function called print_series(a,x,n)
. The
function computes the sum and prints the series along with its sum using
the above format.
At a first glance, the problem seems to be a bit complicated. Also, the series might not make sense to us, because we do not know how it is useful or in which application is it going to be used.
In programming, whenever we find a complicated problem we can always simplify it by breaking it into smaller achievable tasks. In other words, we should always be ready to produce a partial solution. The partial solution can be gradually upgraded to a full solution.
With regards to the usefulness of the series, as programmers doing the implementation, this does not really matter. We just need to make it work. Therefore, this should not be a distraction. Knowing the big picture is more relevant if you are doing a project that would require the application of software engineering principles. But we are not there yet, so let us move on.
We will start by writing the layout of the program. We can write the function definition along with the return value. In this specific example, there is no value to be returned. We can start coding by writing the following:
# Program Name: Prog 6-06
# Solution to Example 6.4
def print_series(a,x,n):
# some code
return
At this stage, it would also be good to write simple main (driver) code
to test the function. This will enable us to test the program as we
progress. The main program contains simple input statements for the
variables a
, x
and n
along with a
function call.
Here is the code:
# Program Name: Prog 6-06
# Solution to Example 6.4
def print_series(a,x,n):
# some code
return
a = int(input('Ente value of a: '))
x = int(input('Enter value of x: '))
n = int(input('Enter value of n: '))
print_series(a,x,n)
If we look at the problem carefully, we can identify that we would need to do three things:
Let us focus on the first task.
We recognize that there are three variables: a
, x
and n
. All of these variables seem to be holding to their
value throughout the series. However, we also see that there is a
variable called i
that progresses from 0
to n
.
This is a good candidate for a for
loop statement. So, we
can write the following:
def print_series(a,x,n):
for i in range(n+1):
#some code
return
At this stage, it should be clear to you why we used (n+1
)
instead of n
in the range
statement.
Next, we can plug-in the mathematical series.
def print_series(a,x,n):
for i in range(n+1):
(a + i)*(x**i)
return
The result of the above expression is not stored anywhere. Therefore, we can store it at a variable of our choice and print it for testing purposes. The code becomes:
def print_series(a,x,n):
for i in range(n+1):
series_term = (a + i)*(x**i)
print(series_term)
return
If you test the above code with values of a = 5, x = 10, n = 6, you get:
Enter value of a: 5
Enter value of x: 10
Enter value of n: 6
5
60
700
8000
90000
1000000
11000000
If you verify the above using a calculator, you will find that the loop is generating the series successfully. Take few moments to celebrate this partial achievement!!
We have seen several examples in Lesson 6 and also recently in Example 6.3.C where we computed a running total using a loop. You can apply the same concept here. The code becomes:
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
return
We can add a print statement for testing:
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
print(f'term = {}, total = {series_term,total}')
return
Running the main program will produce:
Enter value of a: 5
Enter value of x: 10
Enter value of n: 6
term = 5, total = 5
term = 60, total = 65
term = 700, total = 765
term = 8000, total = 8765
term = 90000, total = 98765
term = 1000000, total = 1098765
term = 11000000, total = 12098765
It seems we are progressing faster than what we initially thought. We are ready now to move to the last step.
There are several formatting steps here, but that should not be an issue because again we can start from partial formatting to full formatting.
Let us print the terms one after the other, all in one line, separated by the + operator.
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
print(f'({a}+{i})*{x}**{i} + ',end='')
return
If we run the program, we get:
(5+0)*10**0 + (5+1)*10**1 + (5+2)*10**2 + (5+3)*10**3 + (5+4)*10**4 + (5+5)*10**5 + (5+6)*10**6 +
This is not quite what we want. But we can improve it.
For the first term, we can simply write it in the form a
.
We can do this by adding an if
statement to handle this
special case.
The code becomes:
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
if i == 0:
print(f'{a} + ', end = '')
else:
print(f'({a}+{i})*{x}**{i} + ',end='')
return
Which produces the following output:
5 + (5+1)*10**1 + (5+2)*10**2 + (5+3)*10**3 + (5+4)*10**4 + (5+5)*10**5 + (5+6)*10**6 +
Similarly, we can add a special case for the last term to print the operator = instead of the plus operator. The code becomes:
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
if i == 0:
print(f'{a}', end = '')
else:
print(f'(a{}+{i})*{x}**{i}',end='')
if i == n:
print(' = ', end='')
else:
print(' + ',end='')
return
Observe how we broke the formatting into two if statements to provide better readability. The output becomes:
5 + (5+1)*10**1 + (5+2)*10**2 + (5+3)*10**3 + (5+4)*10**4 + (5+5)*10**5 + (5+6)*10**6 =
Finally, you can add the total at the end of the line using a print
statement outside the for
loop. The code becomes:
def print_series(a,x,n):
total = 0
for i in range(n+1):
series_term = (a + i)*(x**i)
total += series_term
if i == 0:
print(f'{a}', end = '')
else:
print(f'({a}+{i})*{x}**{i}',end='')
if i == n:
print(' = ', end='')
else:
print(' + ',end='')
print(total)
return
The final output will be:
Enter value of a: 5
Enter value of x: 10
Enter value of n: 6
5 + (5+1)*10**1 + (5+2)*10**2 + (5+3)*10**3 + (5+4)*10**4 + (5+5)*10**5 + (5+6)*10**6 = 12098765
This completes the solution.
In this section, we will present some additional operations that will
enhance your use of the for
statement. Although some of
these operations are not essential to your understanding of the for
statement, they would offer you some flexibility and efficiency when
writing your code. We will present three operations: the throwaway
variables, the break-continue
, and the for-else
statement.
In Python, there are instances when you need to define a variable due to syntax requirements, but you end up never using it. Such variables are required to be there, but they are redundant. We call these variables general purpose variables or (as many programmers in the Python community prefer to call it) throwaway variables.
Suppose you would like to print the statement: 'Wear your
seatbelt'
ten times, each appearing on a separate line. This could be
done using a for
statement like the following:
for i in range(10):
print(‘Wear your seatbelt’)
In the above loop, the variable i
is redundant, because it
is never used in the inner block. For such instances, we can use the
following code instead:
for _ in range(10):
print(‘Wear your seatbelt’)
The underscore in the above statement communicates to Python that you do
not care about that variable. Therefore, Python will discard it.
However, it still needs to be there due to the syntax structure of the for
statement.
Technical Note:
The throwaway variable is not a specific feature to the for statement. It could also be used in other statements in Python.
Suppose you have the function find_max_min, which returns the maximum and minimum values from a sequence of numbers. The syntax for calling the function would be:
max_val, min_val = find_max_min(num_seq)
At a specific line of code, if you are only interested in the minimum value, then you can write:
_, min_val = find_max_min(num_seq)
This tells Python to discard the returned max_value, because you are not interested in using it.
In Lesson 6, you were introduced to the break
and continue
commands in the scope of the while
loop statement. Both of
these commands alter the flow of execution, by either forcing an exit
from the loop (break
) or skipping the remaining lines in
the loop (continue
).
The same concept applies to the for
statement. Since you
are familiar with the concept, we will limit the discussion to
presenting an example that demonstrates how both commands are used in for
statements.
Study the following code:
# Program Name: Prog 6-08
def login():
print('System is loading ....')
print('Login screen displayed')
failed_attempts = 0
for _ in range(8):
username = input('Enter username: ')
password = input('Enter password: ')
if username == '' or password == '':
print('One of the fields is empty. Try again')
Continue
1
validated = validate_user(username,password)
if not validated:
failed_attempts += 1
1
if failed_attempts == 3:
print('Your account is locked. Contact your administrator')
Break
2
if validated:
load_system()
logout()
Break
2
print('System is closing')
30. return
3
3 def load_system():
3 #some actions to the load system
3 #is called when user is validated
3 return
3
3 def logout():
3 #some actions to log the user out of system
3 Return
40.
4 def validate_user(username,password):
4 #some actions to see if username/password match
4 return
The program might seem long, but when you analyze it you will find it is
simpler than it appears. The program mainly focuses on the login
function. We are assuming here that there are three other functions: logout
,
validate_user
and load_system
, which we know
work, but we are not interested in knowing how they do that.
Below is a line-by line analysis:
Lines 4,5 | Print statements informing the user that the system is loading and showing the login welcome screen. |
Line 7 | Initializing the variable failed_attempts . This
variable will keep track of how many times the user provides a
username/password combination that does not match.
|
Lines 8 | A for loop statement. This statement will make
the block of code loop 8 times unless it is interrupted. Observe how
the throwaway variable is being used here.
|
Lines 9, 10 | Input statements to get a username and a password from the user. |
Lines 12-14 | If the user forgets to enter the username or password (or both), the loop 'continues' meaning it goes back to line 8 asking the user to re-enter their username and password. Observe that because the loop has only 8 iterations, then the user has only 8 chances to leave one field empty. After 8 iterations, the loop stops and the system closes (line 29). |
Lines 16-18 | The validate_user function is called to check if the username and password match. If it matches, the function returns True; otherwise, it is False. If the result is False, the failed_attempts variable is incremented. |
Lines 20-22 | If the user provided a mismatched username/password three times, the loop is interrupted and the program jumps to line 29. |
Lines 24-27 | If the user is validated, then the system is loaded, and once the user finishes, the logout function is called and the loop interrupts. |
Line 29 | A print statement indicating that the program is closing. |
Lines 32-43 | Empty implementation for the functions logout, validate_user and load_system. |
The above code does elaborate how break
and continue
are used in for
loops. However, it might have given you
some discomfort on how it is structured. You might be thinking that
there are better ways to implement the function. Your intuition is
correct. Specifically, in the for
statement, we want to
avoid using break
and continue
statements
unless they are necessary. We interpret 'necessary' here as having code,
which would be considered 'worse' if break/continue were not used.
Again, the term 'worse' here is subjective and could refer to various
things like readability, efficiency or simplicity.
An extension to the break
statement, Python offers a
special structure called for-else
. The syntax of this
statement is as follows:
for <var> in <iterable>:
<block code 1>
else:
<block code 2>
The for loop block (Block code 1) will execute normally, and once it
completes it will go to the else statement and execute (Block code 2).
Right! This sounds confusing because it is different than the if-else
statement, when only one block will be executed.
However, if there is a break statement in <block code 1> and it was executed, then the program exits the for loop and also jumps over the else statement.
Therefore, we can read the statement as follows:
Execute the for loop. If the loop completes normally, execute the else block. But if the loop is interrupted by a break statement, then exit the loop and the else blocks.
Using the for-else statement is discouraged, and it is rarely used by Python programmers. Therefore, we will not elaborate further on the discussion. It was presented in this Lesson for completeness purposes and for readability purposes in case you encounter code that uses such structure.
for
Loops
Similar to the if and while statements, it is possible to have a for loop enclosed within another for loop. We can also have a for loop inside a while loop and vice versa. The Python language does not put a limit on how many layers we can use. However, we will limit the discussion to a single loop inside another loop.
In Lesson 11, when you study the topic of two dimensional lists, you will frequently use a nested for loop. For now, we will present an example to demonstrate the concept.
Example 6.6:
Write a Python program to draw a rectangle of given length and width. The width represents the number of lines (rows), while the length represents the number of columns. Use the character * to draw the rectangle.
The above example is a classical problem for using a nested for loop. We need to construct two loops. The outer loop controls the printing of lines (rows), and the inner loop controls the number of columns. Let us have a look at the code:
# Program Name: Prog 6-09
# Solution to Example 6.6
def draw_rectangle(length,width):
for _ in range(width):
for _ in range(length):
print('*',end='')
print()
return
length = int(input('Enter length: '))
width = int(input('Enter width: '))
draw_rectangle(length,width)
The outer loop does two things: calling the inner loop and printing a new line once the inner loop is complete. The inner loop controls how many * to print in each iteration. The combined effort of both loops would produce an output similar to the following:
Enter length: 16
Enter width: 4
****************
****************
****************
****************
You might want to experiment with passing negative values or 0 as length and width and check the output.
In Lesson 6, you learned about the second iterative command in Python:
the for
statement. You can
now read and write commands using for
loops.You should
understand now the relationship between the for
statement
and iterable objects in Python. Also, you understand how range
operates in a for
statement and how it is used to generate
number sequences. Finally, you were introduced to some additional
features along with how to identify problems which are better solved
using a for
statement.
In the next lesson, you will learn while loops.