On 30/05/2018 17:05, Peter O'Connor wrote:
On Thu, May 24, 2018 at 2:49 PM, Steven D'Aprano <[email protected]
<mailto:[email protected]>> wrote:
On Thu, May 24, 2018 at 02:06:03PM +0200, Peter O'Connor wrote:
> 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.
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.
You're right, having re-thought it, it seems that the correct way to
write it would be to define both of them in the scope of the
comprehension:
smooth_signal = [average given average=(1-decay)*average + decay*x
for x in signal given average=0.]
This makes sense and follows a simple rule: "B given A" just causes A
to be executed before B - that holds true whether B is a variable or a
loop declaration like "for x in x_gen".
So
a_gen = (g(a) given a=f(a, x) for x in x_gen given a=0)
would be a compact form of:
def a_gen_func(x_gen):
a=0
for x in x_gen:
a = f(a, x)
yield g(a)
a_gen = a_gen_func()
[There is a typo here - a_gen_func is defined to take 1 argument but is
called with none.]
After - *I think* - understanding this, I would try to make the one-line
clearer by parenthesizing it thus (whether or not the grammar required it):
a_gen = ( ((g(a) given a=f(a, x)) for x in x_gen) given a=0)
Even then, it would make my head spin if I came across it. I hope
no-one would write code like that.
I'm not keen on given, but I must admit that ISTM that this example
shows something that can only be done with given: putting some
initialisation, viz. "a=0", into a generator expression. With :=, it
would need a trick:
a_gen = (g( a:=f(a, x) ) for x in [x_gen, a:=0][0] )
or
a_gen = (g( a:=f(a, x) ) for a in [0] for x in x_gen] )
Of course, in the case of a list comprehension (as opposed to a genexp),
the initialisation could be done separately:
a = 0
a_list = [g( a:=f(a, x) ) for x in x_gen]
Rob Cliffe
_______________________________________________
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/