<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 24, 2018 at 2:49 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Thu, May 24, 2018 at 02:06:03PM +0200, Peter O'Connor wrote:</span><span class=""><br>
> We could use given for both the in-loop variable update and the variable<br>
> initialization:<br>
> smooth_signal = [average given average=(1-decay)*average + decay*x for<br>
> x in signal] given average=0.</span><br>
<br>
So in your example, the OUTER "given" creates a local variable in the <br>
current scope, average=0, but the INNER "given" inside the comprehension <br>
exists inside a separate, sub-local comprehension scope, where you will <br>
get an UnboundLocalError when it tries to evaluate (1-decay)*average the <br>
first time.</blockquote><div><br></div><div>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:</div><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> smooth_signal = [average given average=(1-decay)*average + decay*x for</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> x in signal <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">given average=0.</span>] </span><br></div><div><br></div><div>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".</div><div><br></div><div>So </div><div><br></div><div> a_gen = (g(a) given a=f(a, x) for x in x_gen given a=0)</div><div><br></div><div>would be a compact form of:</div><div><br></div><div> def <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">a_gen_func</span>(x_gen):</div><div> a=0</div><div> for x in x_gen:</div><div> a = f(a, x)</div><div> yield g(a)</div><div> </div><div> a_gen = a_gen_func()</div><div><br></div><div><br></div><div> </div></div><br></div></div>