Is this a good use for lambda

Terry Reedy tjreedy at
Thu Dec 23 01:15:09 CET 2004

"Nick Coghlan" <ncoghlan at> wrote in message 
news:41C97407.7090301 at
> Although if you genuinely prefer a functional programming style,
> I'd go with  Terry's answer rather than mine.

The 'iterative' version can also be written recursively, which to most is 
functional.  For me, the important question for general composition is 
whether one unpacks the sequence of functions to construct a nested 
sequence of wrappers (via compose2) *before* one has any data to apply it 
to, or whether one bundles the flat list of functions, as it is, with a 
generic composer which, once it gets a piece of data to operate on, unpacks 
and applies the functions one at a time.  The former has a certain 
theoretical elegance, the latter seems more practical and, for Python, 
probably faster.  So my previous answer was about how the make the former 
approach perhaps clearer, by explicit naming compose2, but not a claim that 
it is necessarily the 'better' approach.

> (Incidentally, I didn't even know what the reduce trap *was* until Terry 
> described it, but the iterative version avoids it automatically)

Yes, I noticed that   A properly-written recursive version of the unpack 
and apply algorithm would do the same.

To me, Python's builtin reduce has two related problems.  The second is 
that it overlays two related but distinct functions, one with three 
parameters and the other, a special case, with just two.  The first problem 
is that as one way to do the second, it defines the three parameter 
function with contradictory parameter orders.

To explain the first:  the three-param signature of Python's reduce is
reduce(update_result_with_item, items, initial_result)
The order of result and item(s) is switched between the update function and 
reduce itself.  Some people (including GvR according to a post on PyDev) 
find this confusing and error-prone enough that they avoid using reduce.

The proper, order-consistent signature is either
reduce(update_result_with_item, initial_result, items)
or possibly (but I prefer the above)
reduce(apply_item_toupdate_result, items, initial_result)
so that the order of the args to the update function matchwa the order they 
are given to reduce.

As to the second problem: if the abbreviated and slightly specialized
reduce1(updater, items), equivalent to
def reduce1(updater, items):
    if items: return reduce(updater, items[0], items[1:])
    else raise TypeError("reduce1 requires at least 1 item")
is important enough to be in builtins, then perhaps it was/is important 
enough to have its own name instead of being overlayed on reduce with a 
perverted signature.  (Though, reduce1(applier, items) *could* be overlayed 
on full reduce with the second consistent signature).

Terry J. Reedy

More information about the Python-list mailing list