[Python-ideas] Inline assignments using "given" clauses

Greg Ewing greg.ewing at canterbury.ac.nz
Mon May 14 05:17:03 EDT 2018


Tim Peters wrote:
> Because you never _need_ to use an assignment expression to write a
> listcomp/genexp.

This whole discussion started because someone wanted a way
to bind a temporary result for use *within* a comprehension.
Those use cases don't require leakage.

> Otherwise it's essentially impossible to explain why:
> 
>     total = 0
>     sums = [total := total + value for value in data]
>     assert sums[-1] == total
> 
> "blows up", despite that its intent is obvious,unless you first
> explain to a user how the listcomp is implemented via an invisible
> synthetic function created by magic, inside of which `total`  has
> nothing to do with the `total` they see on the first line.

It's no harder to explain that than it is to explain
why

    x = 42
    y = [x * x for x in range(5)]
    print(x)

prints 42 rather than whatever value was last bound to
the x in the comprehension.

Seems to me it would be easier to explain that *all* names
bound within a comprehension are local to the comprehension,
than to have to say that some are and some aren't.

-- 
Greg



> UnboundLocalError - WTF?
> 
> That's why leaking "is good".  It works both directions:  the outer
> name leaks _into_ the body too, not just _out_ of it.  Things that
> "look like" they should obviously work do work then, and a user can
> remain blissfully unaware of the implementation.. Of course you can
> also find cases in which it's not wanted.
> 
> If it doesn't leak the kind of use shown above can't be done at all
> via listcomps (at least not straightforwardly).
> 
> If it does leak, the subset of cases where leaking is unwanted _of_
> the subset of cases in which a listcomp//genexp uses an assignment
> expression at all are indeed inconvenienced.
> 
> So - surprise!  It's a tradeoff, something we've never faced before ;-)



More information about the Python-ideas mailing list