(original) (raw)

On Mon, May 14, 2018, 03:36 Chris Angelico <rosuav@gmail.com> wrote:
Guido has stated that this parallel is desired and important:

result = \[f(x) for x in iter if g(x)\]
result = list(f(x) for x in iter if g(x))

Obviously the genexp has to be implemented with a nested function,
since there's no guarantee that it'll be iterated over in this way.
With current semantics, you can easily prove that a list comp is
implemented with a function by looking at how it interacts with other
scopes (mainly class scope), but Tim's proposal may change that.

So I'm looking for examples that prove that a list comp is executed
inside an implicit function. Ideally, examples that are supported by
language guarantees, but something that's "CPython has done it this
way since 3.0" is important too.

I'm aware of just two: the name lookup interaction that may be
changing, and the fact that there's an extra line in a traceback. And
the latter, as far as I know, is not guaranteed (and I doubt anyone
would care if it changed). Are there any other provable points?

Related to the traceback one: the extra stack frame shows up in a debugger, and a profiler counts the extra frame separately. The first often confuses me because I don't immediately see which frame I'm in just by seeing the line of code.

There are odd interactions between \`yield\`/\`yield from\` and comprehensions that was discussed some months ago: "\[Python-Dev\] Tricky way of of creating a generator via a comprehension expression". Wait, is this a continuation of that discussion?