GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — For-else deserves its own section in the tutorial by nedbat · Pull Request #123946 · python/cpython

Conversation

@nedbat

@nedbat nedbat commented Sep 11, 2024 •
edited by github-actions Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

📚 Documentation preview 📚: https://cpython-previews--123946.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

blhsing and rdenadai reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
@nedbat
For-else deserves its own section in the tutorial
5b4cf1c
@bedevere-app bedevere-app Bot added awaiting core review docs Documentation in the Doc dir skip news labels Sep 11, 2024
@nedbat nedbat mentioned this pull request Sep 11, 2024
gh-123786: Clarify else clause in loop statements #123787
Closed
@nedbat nedbat added the skip issue label Sep 11, 2024
blhsing
blhsing reviewed Sep 12, 2024
View reviewed changes
Comment thread Doc/tutorial/controlflow.rst Outdated
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

@blhsing blhsing Sep 12, 2024

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@nedbat nedbat Sep 12, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

blhsing reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@blhsing blhsing Sep 12, 2024

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes that sounds to be in much plainer English to me. 👍

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@AsgerJon AsgerJon Sep 25, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@nedbat
remove mention of unrolling the loop
24be1a9
JelleZijlstra
JelleZijlstra reviewed Sep 25, 2024
View reviewed changes
Comment thread Doc/tutorial/controlflow.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Doc/tutorial/controlflow.rst
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``

@JelleZijlstra JelleZijlstra Sep 25, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@nedbat nedbat Sep 25, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The 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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@nedbat @JelleZijlstra
Update Doc/tutorial/controlflow.rst
b42d86c
Co-authored-by: Jelle Zijlstra <[email protected]>
JelleZijlstra
JelleZijlstra approved these changes Sep 25, 2024
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Sep 25, 2024
@nedbat
nedbat merged commit ffdc80e into python:main Sep 25, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Sep 25, 2024
@nedbat nedbat added needs backport to 3.12 only security fixes needs backport to 3.13 only security fixes labels Sep 25, 2024
@miss-islington-app

miss-islington-app Bot commented Sep 25, 2024

Copy link
Copy Markdown

Thanks @nedbat for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app

miss-islington-app Bot commented Sep 25, 2024

Copy link
Copy Markdown

Thanks @nedbat for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 25, 2024
@nedbat @JelleZijlstra @miss-islington
For-else deserves its own section in the tutorial (pythonGH-123946)
c5d97ff
* For-else deserves its own section in the tutorial

* remove mention of unrolling the loop

* Update Doc/tutorial/controlflow.rst

Co-authored-by: Jelle Zijlstra <[email protected]>

---------

(cherry picked from commit ffdc80e)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
@bedevere-app

bedevere-app Bot commented Sep 25, 2024

Copy link
Copy Markdown

GH-124563 is a backport of this pull request to the 3.12 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 25, 2024
@nedbat @JelleZijlstra @miss-islington
For-else deserves its own section in the tutorial (pythonGH-123946)
5448da1
* For-else deserves its own section in the tutorial

* remove mention of unrolling the loop

* Update Doc/tutorial/controlflow.rst

Co-authored-by: Jelle Zijlstra <[email protected]>

---------

(cherry picked from commit ffdc80e)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
@bedevere-app bedevere-app Bot removed the needs backport to 3.12 only security fixes label Sep 25, 2024
@bedevere-app

bedevere-app Bot commented Sep 25, 2024

Copy link
Copy Markdown

GH-124564 is a backport of this pull request to the 3.13 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Sep 25, 2024
emilyemorehouse added a commit to lysnikolaou/cpython that referenced this pull request Sep 26, 2024
@emilyemorehouse
Merge branch 'main' into fix-help-double-prompt
4cdb3ae
* main: (69 commits)
  Add "annotate" SET_FUNCTION_ATTRIBUTE bit to dis. (python#124566)
  pythongh-124412: Add helpers for converting annotations to source format (python#124551)
  pythongh-119180: Disallow instantiation of ConstEvaluator objects (python#124561)
  For-else deserves its own section in the tutorial (python#123946)
  Add 3.13 as a version option to the crash issue template (python#124560)
  pythongh-123242: Note that type.__annotations__ may not exist (python#124557)
  pythongh-119180: Make FORWARDREF format look at __annotations__ first (python#124479)
  pythonGH-58058: Add quick reference for `ArgumentParser` to argparse docs (pythongh-124227)
  pythongh-41431: Add `datetime.time.strptime()` and `datetime.date.strptime()` (python#120752)
  pythongh-102450: Add ISO-8601 alternative for midnight to `fromisoformat()` calls. (python#105856)
  pythongh-124370: Add "howto" for free-threaded Python (python#124371)
  pythongh-121277: Allow `.. versionadded:: next` in docs (pythonGH-121278)
  pythongh-119400:  make_ssl_certs: update reference test data automatically, pass in expiration dates as parameters python#119400  (pythonGH-119401)
  pythongh-119180: Avoid going through AST and eval() when possible in annotationlib (python#124337)
  pythongh-124448: Update Windows builds to use Tcl/Tk 8.6.15 (pythonGH-124449)
  pythongh-123884 Tee of tee was not producing n independent iterators (pythongh-124490)
  pythongh-124378: Update test_ttk for Tcl/Tk 8.6.15 (pythonGH-124542)
  pythongh-124513: Check args in framelocalsproxy_new() (python#124515)
  pythongh-101100: Add a table of class attributes to the "Custom classes" section of the data model docs (python#124480)
  Doc: Use ``major.minor`` for documentation distribution archive filenames (python#124489)
  ...
JelleZijlstra added a commit that referenced this pull request Sep 26, 2024
@miss-islington @nedbat @JelleZijlstra
[3.12] For-else deserves its own section in the tutorial (GH-123946) (#…
48359c5
…124563)


(cherry picked from commit ffdc80e)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
Yhg1s pushed a commit that referenced this pull request Sep 26, 2024
@miss-islington @nedbat @JelleZijlstra
[3.13] For-else deserves its own section in the tutorial (GH-123946) (#…
56467a6
…124564)

For-else deserves its own section in the tutorial (GH-123946)

* For-else deserves its own section in the tutorial

* remove mention of unrolling the loop

* Update Doc/tutorial/controlflow.rst



---------

(cherry picked from commit ffdc80e)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Jelle Zijlstra <[email protected]>
@JelleZijlstra

JelleZijlstra commented Sep 26, 2024

Copy link
Copy Markdown
Member

@nedbat minor feedback: it's good practice to clean up the commit message before merging so that the git log is more understandable. GitHub's default includes the titles of all the commits, which are often not very informative. In this case, I would have shortened the commit message to just:

For-else deserves its own section in the tutorial

Co-authored-by: Jelle Zijlstra [email protected]

nedbat and AsgerJon reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nedbat
nedbat deleted the nedbat/for-else-tutorial branch September 26, 2024 00:14
@terryjreedy

terryjreedy commented Sep 26, 2024

Copy link
Copy Markdown
Member

I complete agree that break/continue should be separated from else. But I am sorry I did not see this earlier.

Existing lines 203 to 205 after the patch are incomplete. 'else' is paired with any loop exit.

In a :keyword:!for or :keyword:!while loop, any of :keyword:!break, :keyword:!return, and :keyword:!raise: may be paired with an :keyword:!else clause. (There ``raise`` may come from code executed elsewhere.) If the loop finishes without executing and of the 'exit' statements, the :keyword:!else` clause executes.

Ned, do you want to make another PR, or should I?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nedbat

nedbat commented Sep 26, 2024

Copy link
Copy Markdown
Member Author

#124591

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@JelleZijlstra JelleZijlstra JelleZijlstra approved these changes
+2 more reviewers
@blhsing blhsing blhsing left review comments
@AsgerJon AsgerJon AsgerJon left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

docs Documentation in the Doc dir skip issue skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@nedbat @JelleZijlstra @terryjreedy @blhsing @AsgerJon
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.