DekGenius.com
[ Team LiB ] Previous Section Next Section

14.3 Mapping Functions Over Sequences

One of the more common things programs do with lists and other sequences is to apply an operation to each item, and collect the results. For instance, updating all the counters in a list can be done easily with a for loop:

>>> counters = [1, 2, 3, 4]
>>>
>>> updated = [  ]
>>> for x in counters:
...     updated.append(x + 10)              # Add 10 to each item.
...
>>> updated
[11, 12, 13, 14]

Because this is such a common operation, Python provides a built-in that does most of the work for you. The map function applies a passed-in function to each item in a sequence object, and returns a list containing all the function call results. For example:

>>> def inc(x): return x + 10               # function to be run
...
>>> map(inc, counters)                      # Collect results.
[11, 12, 13, 14]

We introduced map as a parallel loop traversal tool in Chapter 10, where we passed in None for the function argument to pair items up. Here, we make better use of it by passing in a real function to be applied to each item in the list—map calls inc on each list item, and collects all the return values into a list.

Since map expects a function to be passed in, it also happens to be one of the places where lambdas commonly appear:

>>> map((lambda x: x + 3), counters)        # Function expression
[4, 5, 6, 7]

Here, the function adds 3 to each item in the counters list; since this function isn't needed elsewhere, it was written inline as a lambda. Because such uses of map are equivalent to for loops, with a little extra code, you could always code a general mapping utility yourself:

>>> def mymap(func, seq):
...     res = [  ]
...     for x in seq: res.append(func(x))
...     return res
...
>>> map(inc, [1, 2, 3])
[11, 12, 13]
>>> mymap(inc, [1, 2, 3])
[11, 12, 13]

However, since map is a built-in, it's always available, always works the same way, and has some performance benefits (in short, it's faster than a for). Moreover, map can be used in more advanced ways than shown; for instance, given multiple sequence arguments, it sends items taken from sequences in parallel as distinct arguments to the function:

>>> pow(3, 4)
81
>>> map(pow, [1, 2, 3], [2, 3, 4])       # 1**2, 2**3, 3**4
[1, 8, 81]

Here, the pow function takes two arguments on each call—one from each sequence passed to map. Although we could simulate this generality too, there is no obvious point in doing so, when map is built-in and quick.

    [ Team LiB ] Previous Section Next Section