[Python-Dev] Generator objects and list comprehensions?
Chris Angelico
rosuav at gmail.com
Wed Jan 25 01:01:18 EST 2017
On Wed, Jan 25, 2017 at 4:38 PM, Craig Rodrigues <rodrigc at freebsd.org> wrote:
>
> Glyph pointed this out to me here:
> http://twistedmatrix.com/pipermail/twisted-python/2017-January/031106.html
>
> If I do this on Python 3.6:
>
>>> [(yield 1) for x in range(10)]
> <generator object <listcomp> at 0x10cd210f8>
>
> If I understand this:
> https://docs.python.org/3/reference/expressions.html#list-displays
> then this is a list display and should give a list, not a generator object.
> Is there a bug in Python, or does the documentation need to be updated?
That looks like an odd interaction between yield expressions and list
comps. Since a list comprehension is actually implemented as a nested
function, your code actually looks more-or-less like this:
>>> def <listcomp>(iter):
result = []
for x in iter:
result.append((yield 1))
return result
>>> <listcomp>(iter(range(10))
<generator object <listcomp> at 0x10cd210f8>
This function is a generator, and calling it returns what you see
above. If you step that iterator, it'll yield 1 ten times, and then
raise StopIteration with the resulting list.
Based on a cursory examination of the issue at hand, I think what
you're working with might be functioning as a coroutine? If so, you
may find that using "await" instead of "yield" dodges the problem, as
it won't turn the list comp into a generator. But I can't be 100%
certain of that. (Also, that would definitely stop you from having
single-codebase 2.7/3.x code.)
ChrisA
More information about the Python-Dev
mailing list