Functional Python Programming
上QQ阅读APP看书,第一时间看更新

Using Python lambda forms

In many cases, the definition of a helper function seems to requires too much code. Often, we can digest the key function to a single expression. It can seem wasteful to have to write both def and return statements to wrap a single expression.

Python offers the lambda form as a way to simplify using higher-order functions. A lambda form allows us to define a small, anonymous function. The function's body is limited to a single expression.

The following is an example of using a simple lambda expression as the key:

long = max(trip, key=lambda leg: leg[2])
short = min(trip, key=lambda leg: leg[2])

The lambda we've used will be given an item from the sequence; in this case, each leg three tuple will be given to the lambda. The lambda argument variable, leg, is assigned and the expression, leg[2], is evaluated, plucking the distance from the three tuple.

In cases where a lambda is used exactly once, this form is ideal. When reusing a lambda, it's important to avoid copy and paste. What's the alternative?

We can assign lambdas to variables, by doing something like this:

start = lambda x: x[0]
end = lambda x: x[1]
dist = lambda x: x[2]  

Each of these lambda forms is a callable object, similar to a defined function. They can be used like a function.

The following is an example at the interactive prompt:

>>> leg = ((27.154167, -80.195663), (29.195168, -81.002998), 129.7748)
>>> start = lambda x: x[0]
>>> end = lambda x: x[1]
>>> dist = lambda x: x[2]
>>> dist(leg)
129.7748  

Python offers us two ways to assign meaningful names to elements of tuples: namedtuples and a collection of lambdas. Both are equivalent. We can use lambdas instead of namedtuples.

To extend this example, we'll look at how we get the latitude or longitude value of the starting or ending point. This is done by defining some additional lambdas.

The following is a continuation of the interactive session:

>>> start(leg)
(27.154167, -80.195663)
 
>>> lat = lambda x: x[0]
>>> lon = lambda x: x[1]
>>> lat(start(leg))
27.154167  

There's no clear advantage to using lambdas as a way to extract fields over namedtuples. A set of lambda objects to extract fields requires more lines of code to define than a namedtuple. On the other hand, lambdas allow the code to rely on prefix function notation, which might be easier to read in a functional programming context. More importantly, as we'll see in the sorted() example later, lambdas can be used more effectively than namedtuple attribute names with sorted(), min(), and max().