Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 37 additions & 16 deletions peps/pep-0798.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ generator::
for x in it:
yield from expr

Since ``yield from`` is not allowed inside of async generators, the equivalent
for ``(*expr async for x in ait())``, is more like the following (though of
course this new form should not define or reference the looping variable
``i``)::
Since ``yield from`` is not allowed inside of async generators (see the section
of :pep:`525` on Asynchronous ``yield from``), the equivalent for ``(*expr
async for x in ait())`` is more like the following (though of course this new
form should not define or reference the looping variable ``i``)::

async def generator():
async for x in ait():
Expand Down Expand Up @@ -557,7 +557,8 @@ by a similar analogy::
for x in it:
out[k_expr] = v_expr

# equivalent to out = {**expr for x in it}
# equivalent to out = {**expr for x in it}, provided that expr evaluates to
# a mapping that can be unpacked with **
out = {}
for x in it:
out.update(expr)
Expand All @@ -577,15 +578,15 @@ expressions that involve unpacking::
yield from expr
g = generator()

We can then generalize from these specific examples to the idea that,
wherever a non-starred comprehension/genexp would use an operator that
adds a single element to a collection, the starred would instead use
an operator that adds multiple elements to that collection.
We can then generalize from these specific examples to the idea that, wherever
a non-starred comprehension/genexp would use an operator that adds a single
element to a collection, the starred would instead use an operator that adds
multiple elements to that collection.

Alternatively, we don't need to think of the two ideas as separate; instead,
with the new syntax, we can think of ``out = [...x... for x in it]`` as
equivalent to the following code [#pep798-guido]_, regardless of whether or not
``...x...`` uses ``*``::
equivalent to the following [#pep798-guido]_ (where ``...x...`` is a stand-in
for arbitrary code), regardless of whether or not ``...x...`` uses ``*``::

out = []
for x in it:
Expand All @@ -595,7 +596,7 @@ Similarly, we can think of ``out = {...x... for x in it}`` as equivalent to the
following code, regardless of whether or not ``...x...`` uses ``*`` or ``**``
or ``:``::

out = set()
out = set() # or out = {}
for x in it:
out.update({...x...})

Expand Down Expand Up @@ -744,45 +745,65 @@ to what is already available in Python, but support for using unpacking syntax
within comprehensions is rare. This section provides a brief summary of
support for similar syntax in a few other languages.

Many languages that support comprehensions support double loops::
Many languages that support comprehensions support double loops:

.. code:: python

# python
[x for xs in [[1,2,3], [], [4,5]] for x in xs * 2]

.. code:: haskell

-- haskell
[x | xs <- [[1,2,3], [], [4,5]], x <- xs ++ xs]

.. code:: julia

# julia
[x for xs in [[1,2,3], [], [4,5]] for x in [xs; xs]]

.. code:: clojure

; clojure
(for [xs [[1 2 3] [] [4 5]] x (concat xs xs)] x)

Several other languages (even those without comprehensions) support these
operations via a built-in function/method to support flattening of nested
structures::
structures:

.. code:: python

# python
list(itertools.chain(*(xs*2 for xs in [[1,2,3], [], [4,5]])))

.. code:: javascript

// Javascript
[[1,2,3], [], [4,5]].flatMap(xs => [...xs, ...xs])

.. code:: haskell

-- haskell
concat (map (\x -> x ++ x) [[1,2,3], [], [4,5]])

.. code:: ruby

# ruby
[[1, 2, 3], [], [4, 5]].flat_map {|e| e * 2}

However, languages that support both comprehension and unpacking do not tend to
allow unpacking within a comprehension. For example, the following expression
in Julia currently leads to a syntax error::
in Julia currently leads to a syntax error:

.. code:: julia

[xs... for xs in [[1,2,3], [], [4,5]]]

As one counterexample, support for a similar syntax was recently added to `Civet
<https://civet.dev/>`_. For example, the following is a valid comprehension in
Civet, making use of Javascript's ``...`` syntax for unpacking::
Civet, making use of Javascript's ``...`` syntax for unpacking:

.. code:: javascript

for xs of [[1,2,3], [], [4,5]] then ...(xs++xs)

Expand Down