Often you need to loop through every item of multiple lists and compare them. This can be done without a using a counter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | a = ['a1', 'a2', 'a3']
b = ['b1', 'b2']
# will iterate 3 times,
# the last iteration, b will be None
print "Map:"
for x, y in map(None, a, b):
print x, y
# will iterate 2 times,
# the third value of a will not be used
print "Zip:"
for x, y in zip(a, b):
print x, y
# will iterate 6 times,
# it will iterate over each b, for each a
# producing a slightly different outpu
print "List:"
for x, y in [(x,y) for x in a for y in b]:
print x, y
|
Using map with "None" as the first argument is discussed in the docs:
"If function is None, the identity function is assumed; if there are multiple list arguments, map() returns a list consisting of tuples containing the corresponding items from all lists (i.e. a kind of transpose operation). The list arguments may be any kind of sequence; the result is always a list."
Note: this returns None for sequences where there is no element. Output:<pre>a1 b1 a2 b2 a3 None</pre>
Zip allows you to iterate over the lists in a similar way, but only up to the number of elements of the smallest list.
Output:<pre>a1 b1 a2 b2</pre>
Python 2.0 introduced list comprehension which explains the rather strange syntax: <pre>[(x,y) for x in a for y in b]</pre> this iterates over the b list for every element in a. These are put into a tuple x, y. We then iterate through that tuple in the outermost for loop.
The result is quite different:<pre>a1 b1 a1 b2 a2 b1 a2 b2 a3 b1 a3 b2</pre>
Mention zip for shortest list? You may want to mention that zip(a, b) could be used where you wanted the shortest list to determine how many cross-sections were taken, rather than the longest list as with map.
Good idea. Mentioned...
loop unrolling.