Why you still need map and filter in Python
Monday, July 27th, 2009This post is written for Python 2.5 (and possibly other Python 2.x series).
In most cases we can use list comprehension instead. Sometimes using map and filter is better for readability. But in rare cases, map and filter are more convenient.
Filter can produce string or tuple
List comprehension always produces a list. This is not nonsense. Filter will produce a string or tuple if the source sequence is a string or tuple. For example:
[x for x in (1,2,3) if x > 1]
returns [2,3].
But
filter((lambda x: x > 1), (1,2,3))
returns (2,3).
Therefore, if you want to filter a string tuple and retain its type in output, using filter is more convenient. Using list comprehension requires type conversion if you want to retain sequence types. For example, to get the same result above but using list comprehension instead of filter:
tuple([x for x in (1,2,3) if x > 1])
This works when you can predict that the source is a tuple (or a string). If not, the situation becomes complex. In that case, you have to write functions to determine the type of the source and convert them accordingly.
Map treats multi-sequences differently
Well, map cannot produce strings or tuples. I guess this is because sometimes the mapping function may become complex, in which cases, retaining the original sequence type becomes unsuitable.
But still, sometimes you may want to use map while dealing with multiple sequences. Both map and list comprehension can handle multiple sequences, but they treat sequences in different ways.
Example:
map(pow, [1,2,3],[2,3,4])
returns [1, 8, 81],
while the analogous list comprehension
[x**y for x in [1,2,3] for y in [2,3,4]]
returns:
[1, 1, 1, 4, 8, 16, 9, 27, 81]
See the difference? In such cases, map and list comprehension are not interchangeable. Well, this is arguable. The roughly equivalent list comprehension is
a=[1,2,3] b=[2,3,4] [a[i]**b[i] for i in range(len(a))]
I guess the map version is more clear. Besides, what if list b is longer than list a? The map function will (probably) raises an error, while list comprehension silently ignores the remaining items.