8.5. for Statement

The other looping mechanism in Python comes to us in the form of the for statement. Unlike the traditional conditional looping for statement found in mainstream third-generation languages (3GLs) like C, Fortran, or Pascal, Python's for is more akin to a scripting language's iterative foreach loop.

8.5.1. General Syntax

Iterative loops index through individual elements of a set and terminate when all the items are exhausted. Python's for statement iterates only through sequences, as indicated in the general syntax here:

							for
							iter_var in sequence:
							suite_to_repeat
						

The sequence sequence will be iterated over, and with each loop, the iter_var iteration variable is set to the current element of the sequence, presumably for use in suite_to_repeat.

8.5.2. Used with Sequence Types

In this section, we will see how the for loop works with the different sequence types. The examples will include string, list, and tuple types.

>>> for eachLetter in 'Names':
…       print 'current letter:', eachLetter
…
current letter: N
current letter: a
current letter: m
current letter: e
current letter: s

When iterating over a string, the iteration variable will always consist of only single characters (strings of length 1). Such constructs may not necessarily be useful. When seeking characters in a string, more often than not, the programmer will either use in to test for membership, or one of the string module functions or string methods to check for substrings.

One place where seeing individual characters does come in handy is during the debugging of sequences in a for loop in an application where you are expecting strings or entire objects to show up in your print statements. If you see individual characters, this is usually a sign that you received a single string rather than a sequence of objects.

There are two basic ways of iterating over a sequence:

Iterating by Sequence Item
>>> nameList ['Walter', "Nicole", 'Steven', 'Henry']
>>> for eachName in nameList:
…        print eachName, "Lim"
…
Walter Lim
Nicole Lim
Steven Lim
Henry Lim

In the above example, a list is iterated over, and for each iteration, the eachName variable contains the list element that we are on for that particular iteration of the loop.

Iterating by Sequence Index

An alternative way of iterating through each item is by index offset into the sequence itself:

>>> nameList = ['Shirley', "Terry", 'Joe', 'Heather', 'Lucy']
>>> for nameIndex in range(len(nameList)):
…       print "Liu,", nameList[nameIndex]
…
Liu, Shirley
Liu, Terry
Liu, Joe
Liu, Heather
Liu, Lucy

Rather than iterating through the elements themselves, we are iterating through the indices of the list.

We employ the assistance of the len() built-in function, which provides the total number of elements in the tuple as well as the range() built-in function (which we will discuss in more detail below) to give us the actual sequence to iterate over.

>>> len(nameList)
5
>>> range(len(nameList))
[0, 1, 2, 3, 4]

Using range(), we obtain a list of the indexes that nameIndex iterates over; and using the slice/subscript operator ( [ ] ), we can obtain the corresponding sequence element.

Those of you who are performance pundits will no doubt recognize that iteration by sequence item wins over iterating via index. If not, this is something to think about. (See Exercise 8-13).

8.5.3. Switch/Case Statement Proxy

Earlier in Section 8.3, we introduced the if-elif-else construct and indicated that Python did not support a switch/case statement. In many cases, an incredibly long set of if-elif-else statements can be replaced by a for loop, which contains the “case” items in a sequence which is iterated over. We present a modified version of the example in Section 8.3, moving all the elif statements into the for loop:

							for cmd in ('add', 'delete', 'quit'):
    if cmd == user.cmd:
        action = cmd + " item"
        valid = 1
        break
							else:
    action = "invalid choice… try again!"
    valid = 0

You are now probably glad to see that there is some kind of substitute for the lack of a switch/case statement in Python, but do you realize that using a list gives you even more power as a programmer? In other languages, the elements of a case statement are constant and a static part of the code. By using lists in Python, not only can these elements be variables, but they can also be dynamic and changed during run-time!

Final note, it may have surprised you to see an else statement at the end there.Yes, else statements can be used with for loops. In this case, the else clause is executed only if the for loop finished to completion. More on else coming up in Section 8.9.

8.5.4. range() [and xrange()] Built-in Function(s)

We mentioned above during our introduction to Python's for loop that it is an iterative looping mechanism. Python also provides a tool that will let us use the for statement in a traditional pseudo-conditional setting, i.e., when counting from one number to another and quitting once the final number has been reached or some condition is no longer satisfied.

The built-in function range() can turn your foreach-like for-loop back into one that you are more familiar with, i.e., counting from zero to ten, or counting from 10 to 100 in increments of 5.

range() Full Syntax

Python presents two different ways to use range(). The full syntax requires that two or all three integer arguments are present:

range( start, end, step=1)

range() will then return a list where for any k, start <= k < end and k iterates from start to end in increments of step. step cannot be 0, or else an error condition will occur.

>>> range(2, 19, 3)
[2, 5, 8, 11, 14, 17]

If step is omitted and only two arguments given, step takes a default value of 1.

>>> range(3,7)
[3, 4, 5, 6]

Let's take a look at an example used in the interpreter environment:

>>> for eachVal in range(2, 19, 3):
…    print "value is:", eachVal
…
value is: 2
value is: 5
value is: 8
value is: 11
value is: 14
value is: 17

Our for loop now “counts” from two to nineteen, incrementing by steps of three. If you are familiar with C, then you will notice the direct correlation between the arguments of range() and those of the variables in the C for loop:

/* equivalent loop in C */
for (eachVal = 2; eachVal < 19; i += 3) {
   printf("value is: %d
", eachVal);
}

Although it seems like a conditional loop now (checking if eachVal<19), reality tells us that range() takes our conditions and generates a list that meets our criteria, which in turn, is used by the same Python for statement.

range() Abbreviated Syntax

range() also has a simple format, which takes one or both integer arguments:

range( start=0, end)

Given both values, this shortened version of range() is exactly the same as the long version of range() taking two parameters with step defaulting to 1. However, if given only a single value, start defaults to zero, and range() returns a list of numbers from zero up to the argument end:

>>> range(5)
[0, 1, 2, 3, 4]

We will now take this to the Python interpreter and plug in for and print statements to arrive at:

>>> for count in range(5):
…       print count
…
0
1
2
3
4

Once range() executes and produces its list result, our expression above is equivalent to the following:

>>> for count in [0, 1, 2, 3, 4]:
…      print count

CORE NOTE: Why not just one syntax for range()?

Now that you know both syntaxes for range(), one nagging question you may have is, why not just combine the two into a single one that looks like this?

range( start=0, end, step=1)# invalid

This syntax will work for a single argument or all three, but not two. It is illegal because the presence of step requires start to be given. In other words, you cannot provide end and step in a two-argument version because they will be (mis)interpreted as start and end.


xrange() Function for Limited Memory Situations

xrange() is similar to range() except that if you have a really large range list, xrange() may come in more handy because it does not have to make a complete copy of the list in memory. This built-in was made for exclusive use in for loops. It doesn't make sense outside a for loop. Also, as you can imagine, the performance will not be as good because the entire list is not in memory.

Now that we've covered all the loops Python has to offer, let us take a look at the peripheral commands that typically go together with loops. These include statements to abandon the loop (break) and to immediately begin the next iteration (continue).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset