From 7fb94fd7a88f14096a509dddd4d8a979a3912672 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 22 Feb 2022 17:26:46 +0000 Subject: bpo-46725: Document starred expressions in for statements (GH-31481) Automerge-Triggered-By: GH:pablogsal --- Doc/reference/compound_stmts.rst | 21 +++++++++++++-------- Doc/whatsnew/3.11.rst | 3 +++ Lib/test/test_grammar.py | 6 ++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index c1ee20e..15a51e7 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -154,17 +154,20 @@ The :keyword:`for` statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object: .. productionlist:: python-grammar - for_stmt: "for" `target_list` "in" `expression_list` ":" `suite` + for_stmt: "for" `target_list` "in" `starred_list` ":" `suite` : ["else" ":" `suite`] The expression list is evaluated once; it should yield an iterable object. An -iterator is created for the result of the ``expression_list``. The suite is -then executed once for each item provided by the iterator, in the order returned -by the iterator. Each item in turn is assigned to the target list using the -standard rules for assignments (see :ref:`assignment`), and then the suite is -executed. When the items are exhausted (which is immediately when the sequence -is empty or an iterator raises a :exc:`StopIteration` exception), the suite in -the :keyword:`!else` clause, if present, is executed, and the loop terminates. +iterator is created for the result of the ``starred_list``. The expression +list can contain starred elements (``*x, *y``) that will be unpacked in the +final iterator (as when constructing a ``tuple`` or ``list`` literal). The +suite is then executed once for each item provided by the iterator, in the +order returned by the iterator. Each item in turn is assigned to the target +list using the standard rules for assignments (see :ref:`assignment`), and then +the suite is executed. When the items are exhausted (which is immediately when +the sequence is empty or an iterator raises a :exc:`StopIteration` exception), +the suite in the :keyword:`!else` clause, if present, is executed, and the loop +terminates. .. index:: statement: break @@ -196,6 +199,8 @@ the built-in function :func:`range` returns an iterator of integers suitable to emulate the effect of Pascal's ``for i := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1, 2]``. +.. versionchanged:: 3.11 + Starred elements are now allowed in the expression list. .. _try: .. _except: diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 98fa7a7..85f12fe 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -160,6 +160,9 @@ traceback. (Contributed by Irit Katriel in :issue:`45607`.) Other Language Changes ====================== +* Starred expressions can be used in :ref:`for statements`. (See + :issue:`46725` for more details.) + * Asynchronous comprehensions are now allowed inside comprehensions in asynchronous functions. Outer comprehensions implicitly become asynchronous. (Contributed by Serhiy Storchaka in :issue:`33346`.) diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 3f5a91a..d35530e 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -1403,6 +1403,12 @@ class GrammarTests(unittest.TestCase): result.append(x) self.assertEqual(result, [1, 2, 3]) + result = [] + a = b = c = [1, 2, 3] + for x in *a, *b, *c: + result.append(x) + self.assertEqual(result, 3 * a) + def test_try(self): ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ### | 'try' ':' suite 'finally' ':' suite -- cgit v0.12