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

Steven D'Aprano steve at pearwood.info
Mon May 14 06:55:02 EDT 2018

On Mon, May 14, 2018 at 09:17:03PM +1200, Greg Ewing wrote:
> 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.

To reiterate what Tim already pointed out, that original usecase 
required a way to feed values *into* the comprehension.


There's no need for dedicated syntax for that if we can just set an 
variable and have it show up in the comprehension.

> 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.

But it *is* harder to explain why comprehensions are their own scope in 
the first place. They don't look like they are in their own scope. They 
look like any other expression.

No other expression (apart from lambda) runs in its own scope. Every 
other scope relates to a clear lexical separation:

- modules
- classes
- functions

except for comprehensions, which just returns a plain old list.

(Generator expressions are a little fuzzier: they at least are 
equivalent to a lambda-with-yield, if such a thing existed.)

It is sometimes useful to be able to reach into a generator expression 
and manipulate a variable between calls. That would make it a coroutine 
(to use the pre-async language), and that's why yield is an expression 
that returns a value, not just a statement.

And it is sometimes useful to be able to see the value of comprehension 
variables after they have finished running.

We have given up all of that to allow ease of implementation to drive 
the semantics, and that's okay. Its a trade-off.

But we can decide the other way too, and choose more useful semantics 
for assignment expressions over an easier implementation.

> 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.

Of course it would be easier to explain. It wouldn't be as useful.

If we wanted "easy to explain", we'd be using BASIC circa 1974, we 
wouldn't have async, generators, comprehensions, exceptions, decorators, 
classes, metaclasses, descriptors, Unicode, or floating point numbers.


More information about the Python-ideas mailing list