computations are repetitive by nature and programming languages have certain loop structures to deal with this. One such loop structure is the for loop.
3.1.1 Example: Printing the 5 Times Table
Assume the task is to print out the 5 times table. Before having learned about loop structures in programming, most of us would first think of coding this like:
When executed, the 10 results are printed quite nicely as
With a for loop, however, the very same printout may be produced by just two (!) lines of code:
With this construction, the loop variable
i takes on each of the values 1 to 10, and for each value, the print function is called.
Since the numbers 1 to 10 appear in square brackets, they constitute a special structure called a list. The loop here would work equally well if the brackets had been dropped, but then the numbers would be a tuple:
Both lists and tuples have certain properties, which we will come back to in Sect. 5.1.
3.1.2 Characteristics of a Typical for Loop
There are different ways to write for loops, but herein, they are typically structured as
where loop_variable runs through the numbersFootnote 1 given by some_numbers. In the very first line, called the for loop header, there are two reserved words, for and in. They are compulsory, as is the colon at the end. Also, the block of code lines inside a loop must be indented. These indented lines are referred to as the loop body. Once the indent is reversed, we are outside (and after) the loop (as commented with # First line after the loop, see code). One run-through of the loop body is called an iteration, i.e., in our example above with the 5 times table, the loop will do 10 iterations.
The name picked for the loop_variable is up to the programmer. In our times table example, the loop variable i appeared explicitly in the print command within the loop. Generally, however, the loop variable is not required to enter in any of the code lines within the loop, it is just available if you need it. This means that if we had, e.g., switched the print command inside our loop with print('Hello!') (i.e., so that i does not appear explicitly within the loop), i would still run through the numbers 1 to 10 as before, but Hello! would be printed 10 times instead.
The loop variable i takes on the values 1 to 10 in the order listed, and any order would be acceptable to Python. Thus, if we (for some reason) would like to reverse the order of the printouts, we could simply reverse the list of numbers, writing [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] instead.
It should be noted that the loop variable is not restricted to run over integers. Our next example includes looping also over floating point values.
Indentation and Nested Loops
In our simple times table example above, the print command inside the loop was indented 4 spaces, which is in accordance with the official style guide of Python.Footnote 2
Strictly speaking, the style guide recommends an indent of 4 spaces per indentation level. What this means, should become clear if we demonstrate how a for loop may appear within another for loop, i.e., if we show an arrangement with nested loops.
The meaning of indentation levels should be clear from the comments (see code), and it is straight forward to use more nested loops than shown here (see, e.g., Exercise 5.7). Note that, together with the colon, indenting is part of the syntax also for other basic programming constructions in Python (e.g., in if-elif-else constructions and functions).
When executing the nested loop construction, we get this printout:
From the printout, we may infer how the execution proceeds. For each value of i, the loop over j runs through all its values before i is updated (or the loop is terminated). To test your understanding of nested loops, you are recommended to do Exercise 5.1.
Other for Loop Structures
In this book, you will occasionally meet for loops with a different structure, and as an example, take a look at this:
Here, in the first iteration, the loop variables i, j and k will become 1, 2 and 3, respectively. In the second iteration, they will become 4, 5 and 6, respectively, and so on. Thus, the printout reads
As usual, each of i, j and k can be used in any desirable way within the loop.
3.1.3 Combining for Loop and Array
Often, loops are used in combination with arrays, so we should understand how that works. To reach this understanding, it is beneficial to do an example with just a small array.
Assume the case is to compute the average height of family members in a family of 5. We may choose to store all the heights in an array, which we then run through by use of a for loop to compute the average. The code (average_height.py) may look like this:
When executed, the code gives 1.5 m as the average height, which compares favorably to a simple hand calculation. What happens here, is that we first sum upFootnote 3 all the heights being stored in the array h, before we divide by the number of family members N (i.e., just like we would do by hand). Observe how sum is initialized to 0 before entering the loop, and that with each iteration, a new height is added to sum. Note that the loop variable i takes on the integer index values of the array, which start with 0 and end with N − 1.
Running Through Code “by Hand”
It is appropriate to stress that much understanding is often developed by first going through code “by hand”, i.e. just read the code while doing calculations by hand, before comparing these hand calculations to what the code produces when run (often some print commands must be inserted in the code to enable detailed comparison).
Thus, to make sure you understand the important details in average_height. py, you are encouraged to go through that code by hand right now. Also, in a copy, insert a print command in the loop, so that you can compare the output from that program to your own calculations, iteration by iteration.
3.1.4 Using the range Function
At this point, the observant reader might argue: “Well, this for loop seems handy, but what if the loop must do a really large number of iterations? If the loop variable is to run through hundreds of numbers, we must spend all day typing those numbers into the loop header”!
This is where the built-in range function enters the picture. When called, the range function will provide integers according to the arguments given in the function call. For example, we could have used range in average_height.py by just changing the header from
Here, range( 0, 5, 1) is a function call, where the function range is told to provide the integers from 0 (inclusive) to 5 (exclusive!) in steps of 1. In this case, range( 0, 5, 1) will provide exactly those numbers that we had in the original code, i.e., the loop variable i will run through the same values (0, 1, 2, 3 and 4) as before, and program computations stay the same.
With a little interactive test, we may confirm that the range function provides the promised numbers. However, since what is returned from the range function is an object of type range, the number sequence is not explicitly available.Footnote 4 Converting the range object to a list, however, does the trick.
A General Call to range
With a header like
and a step > 0, loop_variable will run through the numbers start, start + 1*step, start + 2*step, …., start + n*step, where start + n ∗ step < stop <= start + (n + 1) ∗ step. So, the final number is as close as we can get to the specified stop without equalling, or passing, it. For a negative step (step < 0, example given below), the same thing applies, meaning that the final number can not equal, or be more negative, than the argument stop. Note that an integer step different from 1 and − 1 is perfectly legal.
Different Ways of Calling range
The function range is most often used in for loops to produce a required sequence of integers, but the function is not restricted to for loops only, of course. It may be called in different ways, e.g., utilizing default values. Some examples are
When calling range, there is no argument specifying how many numbers should be produced, like we saw with the linspace function of numpy. With range, this is implied by the function arguments start, stop and step.
Computer Memory Considerations
Note that range does not return all the requested numbers at once. Rather, the call to range will cause the numbers to be provided one by one during loop execution, giving one number per iteration. This way, simultaneous storing of all (loop variable) numbers in computer memory is avoided, which may be very important when there is a large number of loop iterations to make.
3.1.5 Using break and continue
It is possible to break out of a loop, i.e., to jump directly to the first code line after the loop, by use of a break statement. This might be desirable, for example, if a certain condition is met during loop execution, which makes the remaining iterations redundant.
With loops, it may also become relevant to skip any remaining statements of an ongoing iteration, and rather proceed directly with the next iteration. That is, contrary to the “loop stop” caused by a break statement, the loop continues to run after a continue statement, unless the end of the loop has been reached.
An example of how to use break and continue can be found in Sect. 5.2 (times_tables_4.py).
The break and continue statements may also be used in while loops, to be treated next.