[Python-ideas] Proposal: A Reduce-Map Comprehension and a "last" builtin

Paul Moore p.f.moore at gmail.com
Thu Apr 5 17:55:48 EDT 2018


On 5 April 2018 at 22:26, Peter O'Connor <peter.ed.oconnor at gmail.com> wrote:
> I find this a bit awkward, and maintain that it would be nice to have this
> as a built-in language construct to do this natively.  You have to admit:
>
>     smooth_signal = [average = (1-decay)*average + decay*x for x in signal
> from average=0.]
>
> Is a lot cleaner and more intuitive than:
>
>     dev compute_avg(avg, x):
>         return (1 - decay)*avg + decay * x
>
>     smooth_signal =
> itertools.islice(itertools.accumulate(itertools.chain([initial_average],
> signal), compute_avg), 1, None)

Not really, I don't... In fact, factoring out compute_avg() is the
first step I'd take in converting the proposed syntax into something
I'd find readable and maintainable. (It's worth remembering that when
you understand the subject of the code very well, it's a lot easier to
follow complex constructs, than when you're less familiar with it -
and the person who's unfamiliar with it could easily be you in a few
months).

The string of itertools functions are *not* readable, but I'd fix that
by expanding them into an explicit loop:

    smooth_signal = []
    average = 0
    for x in signal:
        average = compute_avg(average, x)
        smooth_signal.append(average)

If I have that wrong, it's because I misread *both* the itertools
calls *and* the proposed syntax. But I doubt anyone would claim that
it's possible to misunderstand the explicit loop.

> Moreover, if added with the "last" builtin proposed in the link, it could
> also kill the need for reduce, as you could instead use:
>
>     last_smooth_signal = last(average = (1-decay)*average + decay*x for x in
> signal from average=0.)

    last_smooth_signal = 0
    for x in signal:
        last_smooth_signal = compute_avg(last_smooth_signal, x)

or functools.reduce(compute_avg, signal, 0), if you prefer reduce() -
I'm not sure I do.

Sorry, this example has pretty much confirmed for me that an explicit
loop is *far* more readable.

Paul.


More information about the Python-ideas mailing list