[Tutor] Beginner's question: Looping through variable & list simultaneously
Steven D'Aprano
steve at pearwood.info
Tue Dec 3 16:51:52 CET 2013
On Tue, Dec 03, 2013 at 01:55:31PM +0100, Rafael Knuth wrote:
> Hej there,
>
> I am writing a little throw away program in order to better understand
> how I can loop through a variable and a list at the same time.
I'm afraid you may be slightly confused as to what is going on with
for-loops in Python. For-loops in Python *always*, without exception,
loop over the items of a "list".
I've put list in quotation marks here because it's not necessarily an
*actual* list, but it can be anything which is list-like. But the
important thing is that Python doesn't have anything like the C-style
for loops:
for ( x = 0; x < 10; x++ ) {
something;
}
or Pascal:
for i := 1 to 100 do
something;
So what is going on when you use a for-loop in Python?
Python for-loops are what some other languages call a "for-each loop",
it expects a collection or sequence of values, and then sets the loop
variable to each value in turn. So we can loop over a list:
for item in [2, "three", 23]:
print(item)
will print each of 2, "three" and 23. This is equivalent to this
pseudo-code:
sequence = [2, "three", 23]
get the first item of sequence # in this case, 2
set loop variable "item" equal to that item
execute the body of the loop
get the second item of sequence # "three"
set loop variable "item" to that item
execute the body of the loop
and so on, until you run out of items.
It isn't just lists that this process works on. It works with strings:
for char in "Hello":
print(char)
will print "H", "e", "l", "l", and "o".
It works with tuples, sets, dicts, and many other objects. It even works
with range objects.
What is a range object? Range objects are a special sort of object which
are designed to provide a series of integer values. In Python 2, there
are two related functions:
range, which actually returns a list
xrange, which is like range except it generates values lazily,
only when requested.
So in Python 2, range(900000) creates a list containing the first 900
thousand integers. xrange(900000) creates a special object which
prepares to create those 900 thousand integers, but doesn't actually do
so until needed. So xrange is more memory-efficient in Python 2.
In Python 3, xrange has been renamed to just plain old "range", and the
old range that creates a list up front is gone.
But the important thing to learn from this is that range (or xrange) is
just an object, a sequence object like lists and tuples and strings and
all sorts of other things. You can't do this in Pascal:
values := 1 to 10;
for i := values do
something;
but in Python we can:
values = list(range(10))
values.append(20)
values.append(30)
for value in values:
print(value)
prints 0, 1, 2, through 9, 20, 30.
The values in the sequence can be anything, including tuples:
py> for item in [(1, 2), (3, 4), (5, 6)]:
... x = item[0]
... y = item[1]
... print(x+y)
...
3
7
11
There's a shorter way to write that:
py> for x,y in [(1, 2), (3, 4), (5, 6)]:
... print(x+y)
...
3
7
11
You don't have to write out the pairs values by hand. Python comes with
some functions to join two or more sets of values into one. The most
important is the zip() function, so called because it "zips up" two
sequences into a single sequence. So we can do this:
py> for x, y in zip([1, 3, 5], [2, 4, 6]):
... print(x+y)
3
7
11
In this case, zip() takes the two lists and returns a single sequence of
values (1,2), (3,4) and (5,6).
The zip function works with any number of sequences:
zip([1, 2, 3], "abc", "XYZ", (4, 5, 6), range(50, 100))
will give:
(1, "a", "X", 4, 50)
(2, "b", "Y", 5, 51)
(3, "c", "Z", 6, 52)
Here's a modification to your earlier code using zip:
PopularCountries = ["Brazil", "China", "France", "India", "Vietnam"]
Backpackers = 1000000
msg = "In %d there were %d backpackers worldwide and their most popular country was %s."
for year, country in zip(range(2009, 2014), PopularCountries):
Backpackers = Backpackers*1.15
print(msg % (year, Backpackers, country))
Hope this helps!
--
Steven
More information about the Tutor
mailing list