-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
For-else deserves its own section in the tutorial #123946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As noted in Discourse, I think the concept of “loop unrolling” may sound too foreign to novices reading a tutorial. The paragraph may serve the purpose just as well without this sentence. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes that sounds to be in much plainer English to me. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recently wrote about this elsewhere and even included an example: class Integer:
__fallback_value__ = 0
__inner_value__ = None
def __init__(self, *args) -> None:
"""This constructor method accepts any number of positional arguments.
It then implements the under-used and underappreciated 'for-loop'
ending with an 'else' clause. The code in the 'else' block runs
after the loop completes. The point is that the 'break' keyword also
applies to this block. So if 'break' is encountered, the code in the
'else' block does not run. To translate to natural language:
'Go through each positional argument and when you find an integer,
assign it to the inner value. Use the fallback value if you have not found any integer
after looking through each positional argument.'
It is the opinion of this author that the 'else' clause in a loop is
both underused and underappreciated."""
for arg in args:
if isinstance(arg, int):
self.__inner_value__ = arg
break
else:
self.__inner_value__ = self.__fallback_value__ Hope this helps in some small way! |
||
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`` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this paragraph necessary? Many readers of the tutorial will not be familiar with try/else, so I'm not sure this helps many people. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't expect people to read purely linearly, and this could help cement the semantics in the reader's mind. |
||
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: | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.