Functional Python Programming

(Wang) #1

Higher-order Functions


We'd like to be able to express f(sel2(s_e_d)) for s_e_d in trip. This involves
functional composition; we're combining a function like to_miles() and a selector
like sel2(). We can express functional composition in Python using yet another
lambda, as follows:


to_miles= lambda s_e_d: to_miles(sel2(s_e_d))


This gives us a longer but more general version of unwrapping, as follows:


to_miles(s_e_d) for s_e_d in trip


While this second version is somewhat more general, it doesn't seem wonderfully
helpful. When used with particularly complex tuples, however, it can be handy.


What's important to note about our higher-order convert() function is that we're
accepting a function as an argument and returning a function as a result. The
convert() function is not a generator function; it doesn't yield anything. The
result of the convert() function is a generator expression that must be evaluated to
accumulate the individual values.


The same design principle works to create hybrid filters instead of mappings.
We'd apply the filter in an if clause of the generator expression that was returned.


Of course, we can combine mapping and filtering to create yet more complex
functions. It might seem like a good idea to create more complex functions to limit
the amount of processing. This isn't always true; a complex function might not beat
the performance of a nested use of simple map() and filter() functions. Generally,
we only want to create a more complex function if it encapsulates a concept and
makes the software easier to understand.


Wrapping additional data while mapping


When we use a construct such as ((f(x), x) for x in C), we've done a wrapping
to create a multi-valued tuple while also applying a mapping. This is a common
technique to save derived results to create constructs that have the benefits of
avoiding recalculation without the liability of complex state-changing objects.


This is part of the example shown in Chapter 4, Working with Collections, to create the
trip data from the path of points. The code looks like this:


from ch02_ex3 import float_from_pair, lat_lon_kml, limits, haversine,
legs


path= float_from_pair(lat_lon_kml())


trip= tuple((start, end, round(haversine(start, end),4)) for
start,end in legs(iter(path)))

Free download pdf