[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" 
proposal. He doesn't want to support your example. (Nick, please correct 
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 
that it won't help your use-case.


-- 
Steve


More information about the Python-ideas mailing list