<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 30/05/2018 17:05, Peter O'Connor
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CACCbJKojtGUnZPWMvidqTLDn3bi6RjyoxxZKqXRWPPEFWzT63g@mail.gmail.com">
      <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"
                moz-do-not-send="true">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>
        </div>
      </div>
    </blockquote>
    [There is a typo here - a_gen_func is defined to take 1 argument but
    is called with none.]<br>
    <br>
    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):<br>
    <br>
        a_gen = ( ((g(a) given a=f(a, x)) for x in x_gen) given a=0)<br>
    <br>
    Even then, it would make my head spin if I came across it.  I hope
    no-one would write code like that.<br>
    <br>
    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:<br>
        a_gen = (g( a:=f(a, x) ) for x in [x_gen, a:=0][0] )<br>
    or<br>
        a_gen = (g( a:=f(a, x) ) for a in [0] for x in x_gen] )<br>
    <br>
    Of course, in the case of a list comprehension (as opposed to a
    genexp), the initialisation could be done separately:<br>
        a = 0<br>
        a_list = [g( a:=f(a, x) ) for x in x_gen]<br>
    <br>
    Rob Cliffe<br>
  </body>
</html>