Python Tutorial Was: Guido's regrets: filter and map

Bengt Richter bokr at oz.net
Wed Nov 27 12:27:02 EST 2002


On 27 Nov 2002 11:19:29 +0100, Bernhard Herzog <bh at intevation.de> wrote:

>Lulu of the Lotus-Eaters <mertz at gnosis.cx> writes:
>
>> Actually... here's an... ummm... "improved" version:
>> 
>> reduce = lambda func, seq, init=None:\
>>          [(l.append(func(l[i],seq[i])),l[-1])
>>                          for l in [[init or seq[0]]]
>>                          for i in range(len(seq))][-1][1]
>
>It doesn't work correctly:
>
>>>> import operator
>>>> reduce(operator.add, [1,2])
>4
>
>That should have been 3.
>
>   Bernhard
>
Nobody(?) seems to have noticed the version I posted the other day:

On 26 Nov 2002 16:21:57 GMT, bokr at oz.net (Bengt Richter) wrote:

>On Mon, 25 Nov 2002 23:19:46 -0800, Terry Hancock <hancock at anansispaceworks.com> wrote:
>[...]
>>
>>map(), filter(), and reduce() do not represent all of the uses for filter,
>>and thus, they can't all be replaced by list comps (BTW, I never used
>>reduce, never understood what it was good for, and don't immediately
>>see how it can be done using list-comps -- would be genuinely interested
>>in seeing a couple of example if anyone's willing). 
>>
>I guess I'll bite:
>
> >>> def lcreduce(fn, seq, init=None):
> ...     return [first
> ...         for first, rest in [ init is None and
> ...             (list(seq[:1]), list(seq[1:])+[id]) or
> ...             ([init], list(seq)+[id])]
> ...         for y in rest if y is id or first.append(fn(first.pop(), y))][0][0]
> ...
> >>> seq = range(10)
> >>> lcreduce(int.__add__,seq)
> 45
> >>> lcreduce(int.__add__,seq,5)
> 50
> >>> seq = (1,2)
> >>> lcreduce(int.__add__,seq)
> 3
> >>> lcreduce(int.__add__,seq,5)
> 8
> >>> seq = [3]
> >>> lcreduce(int.__add__,seq)
> 3
> >>> lcreduce(int.__add__,seq,5)
> 8
> >>> seq = ()
> >>> lcreduce(int.__add__,seq,5)
> 5
> >>> lcreduce(int.__add__,seq)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 3, in lcreduce
> IndexError: list index out of range
>
>But that last is ok:
> >>> reduce(int.__add__,seq)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> TypeError: reduce() of empty sequence with no initial value
>
>I suspect reduce is a little faster than lcreduce ;-)
>
>Regards,
>Bengt Richter

It uses id as a sentinel, which should be generated inside the list comprehension
to be really clean, but it seems to work.

Regards,
Bengt Richter



More information about the Python-list mailing list