diff --git a/peps/pep-0798.rst b/peps/pep-0798.rst index 4a894c2fd2f..3162d56fc94 100644 --- a/peps/pep-0798.rst +++ b/peps/pep-0798.rst @@ -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(): @@ -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) @@ -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: @@ -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...}) @@ -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 `_. 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)