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.