Higher-order Functions
- The generator expression:
(f(x) for x in C) - The generator function:
def mymap(f, C):
for x in C:
yield f(x)
mymap(f, C)
Similarly, we have three ways to apply a filter function to a collection,
all of which are equivalent:
- The filter() function:
filter(f, C) - The generator expression:
(x for x in C if f(x)) - The generator function:
def myfilter(f, C):
for x in C:
if f(x):
yield x
myfilter(f, C)
There are some performance differences; the map() and filter() functions are
fastest. More importantly, there are different kinds of extensions that fit these
mapping and filtering designs, which are as follows:
- We can create a more sophisticated function, g(x), that is applied to each
element, or we can apply a function to the collection, C, prior to processing.
This is the most general approach and applies to all three designs. This is
where the bulk of our functional design energy is invested. - We can tweak the for loop. One obvious tweak is to combine mapping and
filtering into a single operation by extending the generator expression with
an if clause. We can also merge the mymap() and myfilter() functions to
combine mapping and filtering.
The profound change we can make is to alter the structure of the data handled by
the loop. We have a number of design patterns, including wrapping, unwrapping
(or extracting), flattening, and structuring. We've looked at a few of these techniques
in previous chapters.