Search code examples
pythonlist-comprehensionyieldpython-3.7

What are the applications of yield within a comprehension or generator expression?


Python 3.7 documentation mentions that yield expressions are deprecated “in the implicitly nested scopes used to implement comprehensions and generator expressions”, with removal pending for 3.8:

Due to their side effects on the containing scope, yield expressions are not permitted as part of the implicitly defined scopes used to implement comprehensions and generator expressions (in Python 3.7, such expressions emit DeprecationWarning when compiled, in Python 3.8+ they will emit SyntaxError).

I am trying to understand what this change affects (breaks?), because at first glance it addresses a rather esoteric scenario. Is there a good reason for having a yield within a list comprehension or a generator expression in the first place?

So far I came up with these (rather nonsensical) examples, which should be illegal in Python 3.8:

>>> list((yield i) for i in range(5))
[0, None, 1, None, 2, None, 3, None, 4, None]
>>> list([(yield i) for i in range(5)])
[0, 1, 2, 3, 4]

Solution

  • What are the applications of yield within a comprehension or generator expression?

    Nothing.

    This "feature" was confirmed to be a bug and is in the process of being deprecated for python3.7, and will be removed completely in python3.8, resulting in a SyntaxError if used.

    From the docs,

    Yield expressions (both yield and yield from clauses) are now deprecated in comprehensions and generator expressions (aside from the iterable expression in the leftmost for clause). This ensures that comprehensions always immediately return a container of the appropriate type (rather than potentially returning a generator iterator object), while generator expressions won’t attempt to interleave their implicit output with the output from any explicit yield expressions.

    In Python 3.7, such expressions emit DeprecationWarning when compiled, in Python 3.8+ they will emit SyntaxError. (Contributed by Serhiy Storchaka in bpo-10544.)