Skip to content

Commit 0655b63

Browse files
encukoublaisep
andcommitted
gh-141984: Reword the Generator expressions section
Co-authored-by: Blaise Pabon <blaise@gmail.com>
1 parent d8ff4f8 commit 0655b63

1 file changed

Lines changed: 78 additions & 26 deletions

File tree

Doc/reference/expressions.rst

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -956,39 +956,91 @@ Generator expressions
956956
pair: object; generator
957957
single: () (parentheses); generator expression
958958

959-
A generator expression is a compact generator notation in parentheses:
959+
The syntax for :dfn:`generator expressions` is the same as for
960+
list :ref:`comprehensions <comprehensions>`, except that they are enclosed in
961+
parentheses instead of brackets.
962+
For example::
960963

961-
.. productionlist:: python-grammar
962-
generator_expression: "(" `comprehension` ")"
964+
>>> iterator = (x ** 2 for x in range(10))
965+
>>> iterator
966+
<generator object <genexpr> at ...>
967+
968+
At runtime, a generator expression evaluates to a :term:`generator iterator`
969+
which yields the same values as the corresponding list comprehension::
970+
971+
>>> list(iterator)
972+
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
973+
974+
Thus, the example above is roughly equivalent to defining and calling
975+
the following generator function::
976+
977+
def make_generator_of_squares(iterable):
978+
for x in iterable:
979+
yield x**2
980+
981+
make_generator_of_squares(range(10))
982+
983+
The enclosing parentheses can be omitted in calls with only one
984+
positional argument.
985+
See the :ref:`Calls section <calls>` for details.
986+
For example::
987+
988+
# The parentheses after `sum` are part of the call syntax:
989+
>>> sum(x ** 2 for x in range(10))
990+
285
991+
992+
# The generator needs its own parentheses if it's not the only argument:
993+
>>> sum((x ** 2 for x in range(10)), start=1000)
994+
1285
963995

964-
A generator expression yields a new generator object. Its syntax is the same as
965-
for comprehensions, except that it is enclosed in parentheses instead of
966-
brackets or curly braces.
967-
968-
Variables used in the generator expression are evaluated lazily when the
969-
:meth:`~generator.__next__` method is called for the generator object (in the same
970-
fashion as normal generators). However, the iterable expression in the
971-
leftmost :keyword:`!for` clause is immediately evaluated, and the
972-
:term:`iterator` is immediately created for that iterable, so that an error
973-
produced while creating the iterator will be emitted at the point where the generator expression
974-
is defined, rather than at the point where the first value is retrieved.
975-
Subsequent :keyword:`!for` clauses and any filter condition in the leftmost
976-
:keyword:`!for` clause cannot be evaluated in the enclosing scope as they may
977-
depend on the values obtained from the leftmost iterable. For example:
978-
``(x*y for x in range(10) for y in range(x, x+10))``.
979-
980-
The parentheses can be omitted on calls with only one argument. See section
981-
:ref:`calls` for details.
996+
The iterable expression in the leftmost :keyword:`!for` clause is
997+
evaluated immediately, so that an error raised by this expression will be
998+
emitted at the point where the generator expression is defined,
999+
rather than at the point where the first value is retrieved::
1000+
1001+
>>> (x ** 2 for x in nonexistent_iterable)
1002+
Traceback (most recent call last):
1003+
File "<python-input-0>", line 1, in <module>
1004+
...
1005+
NameError: name 'nonexistent_iterable' is not defined
1006+
1007+
All other expressions are evaluated lazily, in the same fashion as normal
1008+
generators (that is, when the iterator is asked to yield a value)::
1009+
1010+
>>> iterator = (nonexistent_value for x in range(10))
1011+
>>> iterator
1012+
<generator object <genexpr> at 0x7f373fb29cb0>
1013+
>>> list(iterator)
1014+
Traceback (most recent call last):
1015+
...
1016+
NameError: name 'nonexistent_value' is not defined
1017+
1018+
::
1019+
1020+
>>> iterator = (x*y for x in range(10) for y in nonexistent_iterable)
1021+
>>> iterator
1022+
<generator object <genexpr> at 0x7f373fcfa500>
1023+
>>> list(iterator)
1024+
Traceback (most recent call last):
1025+
...
1026+
NameError: name 'nonexistent_iterable' is not defined
9821027

9831028
To avoid interfering with the expected operation of the generator expression
984-
itself, ``yield`` and ``yield from`` expressions are prohibited in the
985-
implicitly defined generator.
1029+
itself, ``yield`` and ``yield from`` expressions are prohibited inside
1030+
the implicitly nested scope.
9861031

9871032
If a generator expression contains either :keyword:`!async for`
9881033
clauses or :keyword:`await` expressions it is called an
989-
:dfn:`asynchronous generator expression`. An asynchronous generator
990-
expression returns a new asynchronous generator object,
991-
which is an asynchronous iterator (see :ref:`async-iterators`).
1034+
:dfn:`asynchronous generator expression`.
1035+
An asynchronous generator expression returns a new asynchronous generator
1036+
object, which is an asynchronous iterator (see :ref:`async-iterators`).
1037+
1038+
The formal grammar for generator expressions is:
1039+
1040+
.. grammar-snippet::
1041+
:group: python-grammar
1042+
1043+
generator_expression: "(" `comprehension` ")"
9921044

9931045
.. versionadded:: 3.6
9941046
Asynchronous generator expressions were introduced.

0 commit comments

Comments
 (0)