Python loops
The real power behind computer programming is the ability to make the computer do repetative tasks. In python, we can do this using two tools: for and while loops. The general idea is: let’s say we have a set of instructions that we want the computer to execute more than once. We can place those instructions inside a for or a while loop and the computer will execute the commands some set number of times.
Before we work with some examples, it’s important to grasp the difference between the two types of loops. A for loop executes the instructions a set number of times based on iterating over a sequence. A while loop will do the same thing execpt instead of iterating over a sequence, it will repeat execution of the instructions as long as a specific condition is met.
For loops
In python, the generic syntax of a for loop is:
for element in iterable:
instruction 1
instruction 2
instruction 3
etc...
continue program flow outside of for loop
Three important syntax things to note. First, the for loop definition (the first line) starts with the special word “for” and ends with a colon. Second, the instructions that we want to repeat begin after the definition line and are indented. Each instruction must be indented by the same number of spaces or tabs. Any code that goes back to the indentation level of the for definition itself will not be repeated by that loop.
Iterables
Finally, the for loop in python requires something called an iterable. Iterables are a class of variables that have a specific behavior: you can iterate over them. You’ve already met 2 examples of these: character strings and lists. Let’s look at an example:
[1]:
monthsInYear = 'JFMAMJJASOND'
For our purposes, an iterable will be something that you can move through in sequence or index.
[2]:
print(monthsInYear[3])
A
Just like a list, I can index a string to pull a specific element or elements. This means that I can use a string in a for loop quite easily:
[3]:
for tempelement in monthsInYear:
print(tempelement)
J
F
M
A
M
J
J
A
S
O
N
D
This simple for loop iterates over the variable monthsInYear and repeats the one line of instructions 12 times (1 loop for each element in the variable monthsInYear. Each time that the instructions are executed, the variable tempelement takes on a new value, determined by the next element in the iterable. So, the first time through the loop, the value of tempelement is the first letter of monthsInYear, or “J”. The second time through the loop tempelement becomes “F” and so
on. We know before we run this code that the instructions in the for loop will be executed a specific number of times equal to the number of elements in the variable monthsInyear.
While looping over the elements of a string can be useful, for our purposes as physicists, more often we will iterate over the elements of a list, so let’s do an example.
[11]:
#Argon density (#/m3) in Mars's atmosphere as a function of altitude
#from NASA's MAVEN orbiter
arDensity = [5.81e+03, 6e+03, 1.7e+04, 2.08e+04, 4.31e+04, 6.77e+04, \
1.14e+05, 1.87e+05, 2.8e+05, 4.31e+05]
for dens in arDensity:
print(dens)
5810.0
6000.0
17000.0
20800.0
43100.0
67700.0
114000.0
187000.0
280000.0
431000.0
Just like in the string example, each time through the list my temporary variable, dens in this case, takes on the value of one of the elements of my list. So, the syntax for the for loop is pretty straigtforward. The difficulty comes from knowing when to use the for loop and what instructions to include inside of it. Here we’ve just been doing some printing, but typically, we will want to execute more complex instructions. For example, maybe I would like to know the total argon column
density, or to sum up all of the individual density measurements in our list:
[5]:
totaldensity = 0.0
for dens in arDensity:
totaldensity = totaldensity + dens
print(totaldensity)
1172410.0
Again, note how the print command is executed outside and after the for loop since the indentation of that line is the same as the actual for definition.
For loops using a counter
Sometimes, we want the temporary variable in our for loop to be a counter (0,1,2,3,4…) instead of the actual elements of a list. Then, we can use the counter to index one or more lists and perform operations on them. For example, let’s say that in addition to the argon density above I also knew the CO2 density.
[6]:
co2Density = [2.5e+05,4.9e+05,9.06e+05,1.46e+06,2.71e+06,5.33e+06,9.5e+06,1.71e+07,2.83e+07,4.45e+07]
Now, at each altitude point, I would like to know the sum of the two densities. This would be a little tricky using the notation above becuase I don’t have a good way to store the elements of two lists simultaneously in a temporary variable (e.g. dens above). But, since I know that both lists have the same number of elements and that elements of the same index value correspond to one another (they were taken at the same altitude) I can create a for loop using a counter, and then use
the counter to index both lists simultaneously:
[7]:
CO2_Ar_Density = []
for i in range(len(arDensity)):
CO2_Ar_Density.append(arDensity[i] + co2Density[i])
print(CO2_Ar_Density)
[255810.0, 496000.0, 923000.0, 1480800.0, 2753100.0, 5397700.0, 9614000.0, 17287000.0, 28580000.0, 44931000.0]
Make sure you understand what is happening in this example as this sytnax is used often when working with data in the sciences. First, I created an empty list that would eventually store my Ar + CO2 sum; one element for each altitude level. Then, I created a for loop that uses a counter instead of the values of the arDensity list itself. I did that using the range() function. This function creates a list based on at least 1 argument, the number of elements in the list to be created.
The result is a list that starts at zero and counts by 1 until it gets to the appropriate length:
[8]:
for x in range(len(arDensity)):
print(x)
0
1
2
3
4
5
6
7
8
9
Finally, each time through the loop, I used my counter to index both arDensity and co2Density and add the indexed values together. Then the result is appended to the CO2_Ar_Density list. Again, this would have been tricky to do if I had used the first example of the for loop where I interated over the elements of the list itself. Using a counter is the best way to go when you need to index multiple lists that are correlated in some way.
While loops
Where a for loop will loop over an iterable, the while loop will execute its instructions for as long as a condition is met. In general, a condition is anything that will evaluate to True or False. Let’s look at an example:
[9]:
i = 0
while i < 10:
print(arDensity[i])
i += 1
5810.0
6000.0
17000.0
20800.0
43100.0
67700.0
114000.0
187000.0
280000.0
431000.0
The condition in our while statement is i < 10. As long as that evaluates to True, then the instructions in our loop will continue to be executed. In this example, I increment i by 1 each time through the loop (using i += 1 which is a shortcut for i = i + 1), which means the loop’s instructions will be executed 9 times since we stop when i = 10.
Note that I did this exact same thing above using the for loop. It is often the case that you can perform the same task using either loop. However, the while loop can be particularly useful when you don’t have an iterable that you are working with and instead, you are waiting for a particular value in your program to change in some way. One such example might be something like:
[ ]:
fileHeader = True
while fileHeader:
data = file.readline()
print(data)
if data = "#START":
fileHeader = False
print("all done!")
This will not work as written without a lot of other information, and we haven’t talked about the if statement yet, but this example isn’t to difficult to understand. Here, we start fileHeader off as True, so the condition in the while statement will evaluate to True and the instructions inside the loop will be executed at least once. Then, we do some stuff with a file of some sort and print something. Next, we check to see if the data variable is storing the string
“#START”. If it isn’t, then nothing changes and the instructions will be executed again as fileHeader will continue to have a value of True.
The instructions in the loop will repeat until something in the file causes data to contain the string “#START”. Then the instructions inside the if statement will be executed and fileHeader will be set to False. The next time the while statement is evaluated, it will evaluate to False and the instructions inside the loop will be skipped. Program flow will continue to the instructions after the while loop and in this case a simple statement will be printed.
The example above is a practical example that might be used to read data from a file (something you don’t have to worry about for now). Let’s do a simple example that behaves in the same way that you can execute. Here, I want to use a while loop to remove a stray digit from a string and then print the result. That might look something like:
[ ]:
found = False
text = "I'm like a snake that having swallowed its fill of goose eggs7 can no longer escape through the gaps in the cage."
i = 0
while not found:
if text[i] == "7":
found = True
separationPoint = i
i += 1
print("after the while loop is finished, the 7 has been extracted:", text[0:separationPoint],text[separationPoint+1:])
This code again uses an if statement (more on those in the next lesson) to catch some condition and flip a variable from False to True. Notice that I am using the not logical operator to basically say execute the following commands as long as found evaluates to not True.
A summary
In many cases, it is possible to use a for loop to accomplish the same thing as a while loop and vice versa. Generally, one form or another is more efficient to program and more efficient for the computer to execute. As a general rule, if you are working with iterables, the for loop may be the better option, and if you are not, then the while loop might be easier. Practicing with both will help you learn the situations when one option is preferred over another.