Skip to content

Commit 0713bbc

Browse files
committed
first pass at adding documentation for comprehension unpacking
1 parent 3ebe2f6 commit 0713bbc

File tree

3 files changed

+110
-14
lines changed

3 files changed

+110
-14
lines changed

Doc/reference/expressions.rst

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,17 +266,18 @@ called "displays", each of them in two flavors:
266266
Common syntax elements for comprehensions are:
267267

268268
.. productionlist:: python-grammar
269-
comprehension: `assignment_expression` `comp_for`
269+
comprehension: `flexible_expression` `comp_for`
270270
comp_for: ["async"] "for" `target_list` "in" `or_test` [`comp_iter`]
271271
comp_iter: `comp_for` | `comp_if`
272272
comp_if: "if" `or_test` [`comp_iter`]
273273

274274
The comprehension consists of a single expression followed by at least one
275-
:keyword:`!for` clause and zero or more :keyword:`!for` or :keyword:`!if` clauses.
276-
In this case, the elements of the new container are those that would be produced
277-
by considering each of the :keyword:`!for` or :keyword:`!if` clauses a block,
278-
nesting from left to right, and evaluating the expression to produce an element
279-
each time the innermost block is reached.
275+
:keyword:`!for` clause and zero or more :keyword:`!for` or :keyword:`!if`
276+
clauses. In this case, the elements of the new container are those that would
277+
be produced by considering each of the :keyword:`!for` or :keyword:`!if`
278+
clauses a block, nesting from left to right, and evaluating the expression to
279+
produce an element each time the innermost block is reached. If the expression
280+
is starred, the result will instead be unpacked to produce 0 or more elements.
280281

281282
However, aside from the iterable expression in the leftmost :keyword:`!for` clause,
282283
the comprehension is executed in a separate implicitly nested scope. This ensures
@@ -321,6 +322,9 @@ See also :pep:`530`.
321322
asynchronous functions. Outer comprehensions implicitly become
322323
asynchronous.
323324

325+
.. versionchanged:: 3.15
326+
Unpacking with the ``*`` operator is now allowed in the expression.
327+
324328

325329
.. _lists:
326330

@@ -396,8 +400,8 @@ enclosed in curly braces:
396400
.. productionlist:: python-grammar
397401
dict_display: "{" [`dict_item_list` | `dict_comprehension`] "}"
398402
dict_item_list: `dict_item` ("," `dict_item`)* [","]
403+
dict_comprehension: `dict_item` `comp_for`
399404
dict_item: `expression` ":" `expression` | "**" `or_expr`
400-
dict_comprehension: `expression` ":" `expression` `comp_for`
401405

402406
A dictionary display yields a new dictionary object.
403407

@@ -419,10 +423,21 @@ earlier dict items and earlier dictionary unpackings.
419423
.. versionadded:: 3.5
420424
Unpacking into dictionary displays, originally proposed by :pep:`448`.
421425

422-
A dict comprehension, in contrast to list and set comprehensions, needs two
423-
expressions separated with a colon followed by the usual "for" and "if" clauses.
424-
When the comprehension is run, the resulting key and value elements are inserted
425-
in the new dictionary in the order they are produced.
426+
A dict comprehension may take one of two forms:
427+
428+
The first form uses two expressions separated with a colon followed by the
429+
usual "for" and "if" clauses. When the comprehension is run, the resulting key
430+
and value elements are inserted in the new dictionary in the order they are
431+
produced.
432+
433+
The second form uses a single expression prefixed by the ``**`` dictionary
434+
unpacking operator followed by the usual "for" and "if" clauses. When the
435+
comprehension is run, the expression is evaluated and then unpacked, inserting
436+
0 or more key/value pairs into the new dictionary.
437+
438+
Both forms of dictionary comprehension retain the property that if the same key
439+
is specified multiple times, the associated value in the resulting dictionary
440+
will be the last one specified.
426441

427442
.. index:: pair: immutable; object
428443
hashable
@@ -439,6 +454,8 @@ prevails.
439454
the key. Starting with 3.8, the key is evaluated before the value, as
440455
proposed by :pep:`572`.
441456

457+
.. versionchanged:: 3.15
458+
Unpacking with the ``**`` operator is now allowed in dictionary comprehensions.
442459

443460
.. _genexpr:
444461

@@ -453,7 +470,7 @@ Generator expressions
453470
A generator expression is a compact generator notation in parentheses:
454471

455472
.. productionlist:: python-grammar
456-
generator_expression: "(" `expression` `comp_for` ")"
473+
generator_expression: "(" starred_expression `comp_for` ")"
457474

458475
A generator expression yields a new generator object. Its syntax is the same as
459476
for comprehensions, except that it is enclosed in parentheses instead of

Doc/tutorial/classes.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,25 @@ Examples::
929929
>>> list(data[i] for i in range(len(data)-1, -1, -1))
930930
['f', 'l', 'o', 'g']
931931

932+
>>> x = [[1,2,3], [], [4, 5]]
933+
>>> g = (*i for i in x)
934+
>>> list(g)
935+
[1, 2, 3, 4, 5]
936+
937+
In most cases, generator expressions must be wrapped in parentheses. As a
938+
special case, however, when provided as the sole argument to a function (as in
939+
the examples involving ``sum``, ``set``, ``max``, and ``list`` above), the
940+
generator expression does not need to be wrapped in an additional set of
941+
parentheses. That is to say, the following two pieces of code are semantically
942+
equivalent::
943+
944+
>>> f(x for x in y)
945+
>>> f((x for x in y))
946+
947+
as are the following::
948+
949+
>>> f(*x for x in y)
950+
>>> f((*x for x in y))
932951

933952

934953
.. rubric:: Footnotes

Doc/tutorial/datastructures.rst

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,47 @@ The :func:`zip` function would do a great job for this use case::
333333

334334
See :ref:`tut-unpacking-arguments` for details on the asterisk in this line.
335335

336+
Unpacking in Lists and List Comprehensions
337+
------------------------------------------
338+
339+
The section on :ref:`tut-unpacking-arguments` describes the use of ``*`` to
340+
"unpack" the elements of an iterable object, providing each one seperately as
341+
an argument to a function. Unpacking can also be used in other contexts, for
342+
example, when creating lists. When specifying elements of a list, prefixing an
343+
expression by a ``*`` will unpack the result of that expression, adding each of
344+
its elements to the list we're creating::
345+
346+
>>> x = [1, 2, 3]
347+
>>> [0, *x, 4, 5, 6]
348+
[0, 1, 2, 3, 4, 5, 6]
349+
350+
This only works if the expression following the ``*`` evaluates to an iterable
351+
object; trying to unpack a non-iterable object will raise an exception::
352+
353+
>>> x = 1
354+
>>> [0, *x, 2, 3, 4]
355+
Traceback (most recent call last):
356+
File "<python-input-1>", line 1, in <module>
357+
[0, *x, 2, 3, 4]
358+
TypeError: Value after * must be an iterable, not int
359+
360+
Unpacking can also be used in list comprehensions, as a way to build a new list
361+
representing the concatenation of an arbitrary number of iterables::
362+
363+
>>> x = [[1, 2, 3], [4, 5, 6], [], [7], [8, 9]]
364+
>>> [*element for element in x]
365+
[1, 2, 3, 4, 5, 6, 7, 8, 9]
366+
367+
Note that the effect is that each element from ``x`` is unpacked. This works
368+
for arbitrary iterable objects, not just lists::
369+
370+
>>> x = [[1, 2, 3], 'cat', {'spam': 'eggs'}]
371+
>>> [*element for element in x]
372+
[1, 2, 3, 'c', 'a', 't', 'spam']
373+
374+
But if the objects in ``x`` are not iterable, this expression would again raise
375+
an exception.
376+
336377
.. _tut-del:
337378

338379
The :keyword:`!del` statement
@@ -394,7 +435,10 @@ A tuple consists of a number of values separated by commas, for instance::
394435
>>> v = ([1, 2, 3], [3, 2, 1])
395436
>>> v
396437
([1, 2, 3], [3, 2, 1])
397-
438+
>>> # they support unpacking just like lists:
439+
>>> x = [1,2,3]
440+
>>> 0, *x, 4
441+
(0, 1, 2, 3, 4)
398442

399443
As you see, on output tuples are always enclosed in parentheses, so that nested
400444
tuples are interpreted correctly; they may be input with or without surrounding
@@ -480,12 +524,16 @@ Here is a brief demonstration::
480524
{'r', 'd', 'b', 'm', 'z', 'l'}
481525

482526
Similarly to :ref:`list comprehensions <tut-listcomps>`, set comprehensions
483-
are also supported::
527+
are also supported, including comprehensions with unpacking::
484528

485529
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
486530
>>> a
487531
{'r', 'd'}
488532

533+
>>> fruits = [{'apple', 'avocado', 'apricot'}, {'banana', 'blueberry'}]
534+
>>> {*fruit for fruit in fruits}
535+
{'blueberry', 'banana', 'avocado', 'apple', 'apricot'}
536+
489537

490538
.. _tut-dictionaries:
491539

@@ -563,6 +611,18 @@ arbitrary key and value expressions::
563611
>>> {x: x**2 for x in (2, 4, 6)}
564612
{2: 4, 4: 16, 6: 36}
565613

614+
And dictionary unpacking (via ``**``) can be used to merge multiple
615+
dictionaries::
616+
617+
>>> odds = {i: i**2 for i in (1, 3, 5)}
618+
>>> evens = {i: i**2 for i in (2, 4, 6)}
619+
>>> {**odds, **evens}
620+
{1: 1, 3: 9, 5: 25, 2: 4, 4: 16, 6: 36}
621+
622+
>>> all_values = [odds, evens, {0: 0}]
623+
>>> {**i for i in all_values}
624+
{1: 1, 3: 9, 5: 25, 2: 4, 4: 16, 6: 36, 0: 0}
625+
566626
When the keys are simple strings, it is sometimes easier to specify pairs using
567627
keyword arguments::
568628

0 commit comments

Comments
 (0)