Python tip 23: map, filter and reduce
Many operations on container objects can be defined in terms of these three concepts. For example, if you want to sum the square of all even numbers:
- separating out even numbers is Filter (i.e. only elements that satisfy a condition are retained)
- square of such numbers is Map (i.e. each element is transformed by a mapping function)
- final sum is Reduce (i.e. you get one value out of multiple values)
One or more of these operations may be absent depending on the problem statement. Each of these steps will be first illustrated using straightforward code and then the equivalent list comprehensions (and generator expressions) are also shown.
The first of these steps could look like:
>>> def get_evens(iterable):
... op = []
... for n in iterable:
... if n % 2 == 0:
... op.append(n)
... return op
...
>>> nums = [100, 53, 32, 0, 11, 5, 2]
>>> get_evens(nums)
[100, 32, 0, 2]
>>> [n for n in nums if n % 2 == 0]
[100, 32, 0, 2]
The second step could be:
>>> def sqr_evens(iterable):
... op = []
... for n in iterable:
... if n % 2 == 0:
... op.append(n * n)
... return op
...
>>> sqr_evens(nums)
[10000, 1024, 0, 4]
>>> [n * n for n in nums if n % 2 == 0]
[10000, 1024, 0, 4]
And finally, the third step could be:
>>> def sum_sqr_evens(iterable):
... total = 0
... for n in iterable:
... if n % 2 == 0:
... total += n * n
... return total
...
>>> sum_sqr_evens(nums)
11028
>>> sum(n * n for n in nums if n % 2 == 0)
11028
You can also use map(), filter() and functools.reduce() for such problems.
Video demo:
See also my 100 Page Python Intro ebook.