From 5b4cf1ca6185130eb60333e90556d9e8d4358255 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 11 Sep 2024 07:07:55 -0400 Subject: [PATCH 1/3] For-else deserves its own section in the tutorial --- Doc/tutorial/controlflow.rst | 84 +++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 677d7ca02c3f2f..d3cf1a37501dc9 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -160,16 +160,52 @@ arguments. In chapter :ref:`tut-structures`, we will discuss in more detail abo .. _tut-break: -:keyword:`!break` and :keyword:`!continue` Statements, and :keyword:`!else` Clauses on Loops -============================================================================================ +:keyword:`!break` and :keyword:`!continue` Statements +===================================================== The :keyword:`break` statement breaks out of the innermost enclosing -:keyword:`for` or :keyword:`while` loop. +:keyword:`for` or :keyword:`while` loop:: -A :keyword:`!for` or :keyword:`!while` loop can include an :keyword:`!else` clause. + >>> for n in range(2, 10): + ... for x in range(2, n): + ... if n % x == 0: + ... print(f"{n} equals {x} * {n//x}") + ... break + ... + 4 equals 2 * 2 + 6 equals 2 * 3 + 8 equals 2 * 4 + 9 equals 3 * 3 + +The :keyword:`continue` statement continues with the next +iteration of the loop:: + + >>> for num in range(2, 10): + ... if num % 2 == 0: + ... print(f"Found an even number {num}") + ... continue + ... print(f"Found an odd number {num}") + ... + Found an even number 2 + Found an odd number 3 + Found an even number 4 + Found an odd number 5 + Found an even number 6 + Found an odd number 7 + Found an even number 8 + Found an odd number 9 + +.. _tut-for-else: + +:keyword:`!else` Clauses on Loops +================================= + +In a :keyword:`!for` or :keyword:`!while` loop the :keyword:`!break` statement +may be paired with an :keyword:`!else` clause. If the loop finishes without +executing the break, the else clause executes. In a :keyword:`for` loop, the :keyword:`!else` clause is executed -after the loop reaches its final iteration. +after the loop finishes its final iteration, that is, if no break occurred. In a :keyword:`while` loop, it's executed after the loop's condition becomes false. @@ -198,32 +234,18 @@ which searches for prime numbers:: 9 equals 3 * 3 (Yes, this is the correct code. Look closely: the ``else`` clause belongs to -the :keyword:`for` loop, **not** the :keyword:`if` statement.) - -When used with a loop, the ``else`` clause has more in common with the -``else`` clause of a :keyword:`try` statement than it does with that of -:keyword:`if` statements: a :keyword:`try` statement's ``else`` clause runs -when no exception occurs, and a loop's ``else`` clause runs when no ``break`` -occurs. For more on the :keyword:`!try` statement and exceptions, see -:ref:`tut-handling`. - -The :keyword:`continue` statement, also borrowed from C, continues with the next -iteration of the loop:: - - >>> for num in range(2, 10): - ... if num % 2 == 0: - ... print("Found an even number", num) - ... continue - ... print("Found an odd number", num) - ... - Found an even number 2 - Found an odd number 3 - Found an even number 4 - Found an odd number 5 - Found an even number 6 - Found an odd number 7 - Found an even number 8 - Found an odd number 9 +the ``for`` loop, **not** the ``if`` statement.) + +One way to think of the else clause is to imagine it paired with the ``if`` +inside the loop. If you conceptually unroll the loop, you have an if/if/if/else +structure. The ``if`` is inside the loop, executing a ``break``, and the +``else`` is the else clause outside the loop. + +When used with a loop, the ``else`` clause has more in common with the ``else`` +clause of a :keyword:`try` statement than it does with that of ``if`` +statements: a ``try`` statement's ``else`` clause runs when no exception +occurs, and a loop's ``else`` clause runs when no ``break`` occurs. For more on +the ``try`` statement and exceptions, see :ref:`tut-handling`. .. _tut-pass: From 24be1a9e762b3537c846eb854da63ad20d7dee35 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 25 Sep 2024 18:22:31 -0400 Subject: [PATCH 2/3] remove mention of unrolling the loop --- Doc/tutorial/controlflow.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index d3cf1a37501dc9..b2ef714dcf5db9 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -237,9 +237,10 @@ which searches for prime numbers:: the ``for`` loop, **not** the ``if`` statement.) One way to think of the else clause is to imagine it paired with the ``if`` -inside the loop. If you conceptually unroll the loop, you have an if/if/if/else -structure. The ``if`` is inside the loop, executing a ``break``, and the -``else`` is the else clause outside the loop. +inside the loop. As the loop executes, it will run a sequence like +if/if/if/else. The ``if`` is inside the loop, encountered a number of times. If +the condition is ever true, a ``break`` will happen. If the condition is never +true, the ``else`` clause outside the loop will execute. When used with a loop, the ``else`` clause has more in common with the ``else`` clause of a :keyword:`try` statement than it does with that of ``if`` From b42d86cd3473b272018e86c6e5bca2172dd4448d Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 25 Sep 2024 18:33:36 -0400 Subject: [PATCH 3/3] Update Doc/tutorial/controlflow.rst Co-authored-by: Jelle Zijlstra --- Doc/tutorial/controlflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index b2ef714dcf5db9..c97c65f7a3988e 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -202,7 +202,7 @@ iteration of the loop:: In a :keyword:`!for` or :keyword:`!while` loop the :keyword:`!break` statement may be paired with an :keyword:`!else` clause. If the loop finishes without -executing the break, the else clause executes. +executing the :keyword:`!break`, the :keyword:`!else` clause executes. In a :keyword:`for` loop, the :keyword:`!else` clause is executed after the loop finishes its final iteration, that is, if no break occurred.