More elegant way to avoid this hacky implementation of single line reduce for grouping a collection?

Peter Otten __peter__ at web.de
Sat Jan 26 04:00:44 EST 2019


MRAB wrote:

> On 2019-01-25 22:58, Travis Griggs wrote:
>> 
>>      grouped = reduce(
>>          lambda accum, each: (accum[0],
>>          accum[0][str(each)].append(each)), allValues,
>>          (defaultdict(list), None))[0]
>> 
>> My question, only for the sake of learning python3 fu/enlightenment, is
>> there a simpler way to do this with a reduce? I get there’s lots of way
>> to do a groupby. The pursuit here is what’s the
>> simplest/cleverest/sneakiest way to do it with reduce, especially if the
>> quality that gorupfunc (str() in this example) is only called once per
>> item is persevered.
>> 
> How about this:
> 
> grouped = lambda iterable, groupfunc: dict(reduce(
>      lambda accum, each: accum[groupfunc(each)].append(each) or accum,
>      iterable,
>      defaultdict(list)))

The 

false-expr or ret-val

expression could also be spelt

(false-expr, ret-val)[1]

I suppose the peephole optimiser could be taught to avoid building the 
tuple, i. e.

def thelambda(accum, each):
    return (accum[groupfunc(each)].append(each), accum)[1]

would be compiled to

def thelambda(accum, each):
    accum[groupfunc(each)].append(each)
    return accum





More information about the Python-list mailing list