Is this a good use for lambda

Terry Reedy tjreedy at
Wed Dec 22 04:51:50 CET 2004

"Alan G Isaac" <aisaac at> wrote in message 
news:10sf9hfgnoh9j92 at
>I need a clarification of the argument.
> Are the opponents saying that I should not be able to:

If you define 'opponent to lambda' as one who thinks such, then sure ;-).

> def compose(list_of_functions): return reduce(lambda f, g: lambda x:
> f(g(x)), list_of_functions)
> In a nutshell: why?
> And may I see the proposed "better" replacement for function composition.

The issue with respect to lambda is not whether composition should be 
explicit, by building on a compose2 function, or implict, by induction, but 
whether, in this case, the function that composes two functions should get 
a name like 'compose2' or be anonymous (and generically referred to by 
CPython as '<lambda>'.  To me, the following is clearer to read and hardly 
takes more keystrokes:

def compose2(f, g): return lambda x: f(g(x))
def compose(*callables):return reduce(compose2, callables)

This allows independent use of compose2 and may give a better error message 
should callables include a non-callable.

But understanding either version requires knowing that composition is 
associative, so that reducing left to right with reduce() has the same 
effect as reducing right to left as did with a for loop.  Also, as written, 
both reduce versions fall into the reduce trap and fail with an empty list. 
To avoid this, add the identity function either always:

def compose(*callables): return reduce(compose2, callables, lambda x: x)

or, more efficiently, just when needed:

def compose(*callables):
    if callables: return reduce(compose2, callables)
    else: return lambda x: x

Terry J. Reedy

More information about the Python-list mailing list