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

Steven D'Aprano steve at pearwood.info
Thu May 24 08:49:01 EDT 2018

```On Thu, May 24, 2018 at 02:06:03PM +0200, Peter O'Connor wrote:
> To give this old horse a kick: The "given" syntax in the recent thread
> could give a nice solution for the problem that started this thread.

Your use-case is one of the motivating examples for PEP 572. Unless I'm
confused, your use-case is intentionally left out of Nick's "given"
me if I'm mistaken.)

> Instead of my proposal of:
>    smooth_signal = [average := (1-decay)*average + decay*x for x in signal
> from average=0.]

This would become:

average = 0
smooth_signal = [average := (1-decay)*average + decay*x for x in signal]

under PEP 572. If you insist on a one-liner (say, to win a bet), you
could abuse the "or" operator:

smooth_signal = (average := 0) or [average := (1-decay)*average + decay*x for x in signal]

but I think that's the sort of example that people who dislike this
proposal are worried about so please don't do that in serious code :-)

> We could use given for both the in-loop variable update and the variable
> initialization:
>    smooth_signal =  [average given average=(1-decay)*average + decay*x for
> x in signal] given average=0.

I don't think that will work under Nick's proposal, as Nick does not
want assignments inside the comprehension to be local to the surrounding
scope. (Nick, please correct me if I'm wrong.)

So in your example, the OUTER "given" creates a local variable in the
current scope, average=0, but the INNER "given" inside the comprehension
exists inside a separate, sub-local comprehension scope, where you will
get an UnboundLocalError when it tries to evaluate (1-decay)*average the
first time.

[...]
> So in stead of adding 2 symbols and a keyword, we just need to add the one
> "given" keyword.

PEP 572 will not only have the semantics you desire, but it requires
only a single new symbol. If Nick writes up "given" as a PEP, I expect

--
Steve
```