Computers are ideally suited to run the same piece of code over thousands, if not millions of pieces of data. Doing the same thing over and over again is called iteration and all computer languages have instructions for iteration. The part of the code that is iterated is called a loop. The philosophy behind python's iterative commands is different to all other languages.
python
list = ..... for every item in list: do something |
other languages
for item from start_number to end_number, advance a step of size do something |
In python if you create the list with range(), you have to create the whole list before you start the loop. In the 2nd method, you create one item at a time. In python, if your list is larger than can be held by the memory in your computer, then your program won't run. We'll find an example of this later when calculating π. There we'll use xrange() which generates one item at a time, rather than a list.
Here's example python code which iterates over a list of numbers (the '[' and ']' delineate a list).
#!/usr/bin/python for x in [0,1,2,3,4,5]: print x, |
Code this up as interation_1.py and check that you get reasonable output. What happens if you leave off the ',' at the end of the print statement [64] ?
The body of this loop has one instruction (the print() statement). The length of the loop isn't so obvious: no-one is pedantic about this - including the required blank line at the end, you could say that the loop is 3 lines long, or maybe 2 (the for statement and the print() statement) or maybe 1 (the print() statement).
Note | |||
---|---|---|---|
If you run this code at the python prompt (>>>), you will need a blank line after the print() statement, to let python know that the indentation has changed back to the previous level of nesting (here the left most column). Compare this piece of code
with this piece of code (the only change is the indentation for the print "hello" statement). Predict the output of the two pieces of code and then run the code.
|
Change the code in iteration_1.py to
Here's my code [65] .
Warning | ||
---|---|---|
x (the variable whose value is being set by the for statement) is called the control or loop variable. It's only purpose is as input to the loop statements. The loop variable should be treated as a readonly variable. (i.e. you shouldn't try to change it) i.e. do not put the control variable on the left hand side of any instructions in the loop. DO NOT DO ANY OF THESE
Changing the loop variable is unsafe programming. If you're debugging a long loop, you don't want code in the middle messing with the control variable. In some languages (fortran) you aren't allowed to change the loop variable, or it will change in unpredictable ways. (In python, in this loop above, changing x wouldn't cause any great problems, other than being unsafe programming.) If you want to do something with the control variable, make a copy of it (with say y = x) and do whatever you need on the copy y. |
Using iteration_1.py as a template, write iteration_2.py to output and sum the squares of the numbers 0..5. Here's my first version [66] . Notice that the calculation of x*x is done twice. You shouldn't ever do a calculation twice - it takes too much time. If you need the result in two places, you do the calculation once and save the result in a variable. Here's a better version [67] .
Note | ||
---|---|---|
some new syntax: these are identical
|
Modify iteration_2.py to use this new syntax. Here's my new version [68] .
Most often, you aren't iterating over an irregular or random list of numbers. You usually iterate over a well behaved and ordered list. Rather than enter a list by hand, risking a mistake, python (and a few other languages) have functions to generate lists. Python's command is range() and true to python form, it behaves differently to the equivalent command in other languages.
Here's the way everyone else does it
range(start, end, [step]) #[] indicates an optional parameter, default value here is 1 range (0,10) 0,1,2,3,4,5,6,7,8,9,10 |
Here's python's version
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
The argument (parameter) 10, says to generate the default list (i.e. starts at 0, stepping/spacing of 1) and stop at the element before 10 (simple huh?). In this case range() produces 10 numbers, as you might expect, but see below for further developments.
For fun, try a few other sets of parameters for range().
Copy iteration_2.py to iteration_3.py and use range() to generate the list of numbers from 0..5. Here's my code [69] .
Well that was confusing, if you want to generate a list from 0..5, you need an argument of 6 for range().
Here's some more examples using range().
#as above, starting at 0 >>> range(0,10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #starting at 1, ending element before 10 >>> range(1,10) [1, 2, 3, 4, 5, 6, 7, 8, 9] #starting at 1, in steps of 3, ending at element before 10. >>> range(1,10,3) [1, 4, 7] |
Using the previous code as a template, sum the squares of all the numbers from 0..100. Then sum the squares of all the numbers from 0..100 that are divisible by 7. Here's my code [70] .
Note | |
---|---|
End Lesson 9 |
fencepost error (http://www.eps.mcgill.ca/jargon/jargon.html#fencepost%20error)
We've run into the fencepost error before. when I asked you to march 10h places down the alphabet from 'A'. The correct answer was 'Q', but someone got 'P'.
You want to build a fence 100ft long, in sections of 10'. How many sections of fence will you be building [71] and how many fenceposts do you need [72] ?
Same question again: if I want to sum the squares of the n consecutive integers, how many iterations (of the loop) do I need [73] ? If I want to sum the squares of integers 0..n, and how many iterations do I need [74] ?
This will fool you over and over and over, from the start of your programming career to the end. Anytime you iterate (go) from a start boundary condition, over a range, to an end boundary condition, you'll have to do a test count, to determine whether you're counting fenceposts or fences. (When you're programming, it's not always obvious whether a variable is a fence or a fencepost.) If you've got it wrong and you only have one iteration to do, the computer will think you only have to do 0 iterations. Your loop won't be executed and you'll think that there was something wrong inside the loop, that it didn't add (or whatever) your number.
First Steps to Programming (http://docs.python.org/tut/node5.html#SECTION005200000000000000000) shows a while loop.
A while loop has this structure
determine condition while condition is true do a do b . . determine condition again #code executed when condition becomes false |
The while and for loops can be logically equivalent. These two produce the same output:
while loop
variable = 0 while (variable < 10): variable = variable + 1 print variable |
for loop
for x in range(10) print variable |
The while loop requires a little more setting up, but unlike the for loop which is good for regular input, the while loop can be setup to handle just about anything (here pseudo code accepts a name)
print "enter your name followed by a carriage return" name = "" char = getkeystroke() #I made this function up # != is not equal - the loop is entered for all chars except a carriage return # if the char is a carriage return, which instruction is executed next? while (char != carriage return): char = getkeystroke() name += char print name |
The essential features of the while loop are