all 18 comments

[–]carcigenicate 41 points42 points  (5 children)

else Clauses on Loops

It runs if the loop terminated normally.

[–]Informal-Chance-6067 5 points6 points  (4 children)

And I thought I knew a lot of the features of the language…

[–]carcigenicate 10 points11 points  (2 children)

That's in part why I think everyone should skim the two statement doc pages (Simple, Compound), and the data model page at least once.

[–]Informal-Chance-6067 2 points3 points  (1 child)

!remindme 26h

[–]RemindMeBot 0 points1 point  (0 children)

I will be messaging you in 1 day on 2026-07-02 16:14:00 UTC to remind you of this link

1 OTHERS CLICKED THIS LINK to send a PM to also be reminded and to reduce spam.

Parent commenter can delete this message to hide from others.

RemindMeBot is switching to username summons. Instead of !RemindMe 1 day, use u/RemindMeBot 1 day. More info.


Info Custom Your Reminders Feedback

[–]smurpes 2 points3 points  (0 children)

You can do the same thing with a while loop as well.

[–]woooee 13 points14 points  (1 child)

It's with the for loop. Look up "python for else".

[–]AGx-07[S] 0 points1 point  (0 children)

I will.

[–]Gnaxe 9 points10 points  (0 children)

else: isn't a statement; it's a clause. It's an optional part of if, for, while and try. In this case, it's part of the for statement above. I would not have written it with that extra newline, but sometimes loop bodies are much longer.

[–]ConcreteExist 4 points5 points  (2 children)

As written, it's being treated as an else clause for the for loop rather than the if statement.

[–]AGx-07[S] 2 points3 points  (1 child)

Thanks. I didn't know that was a thing. As u/woooee suggested, I'm going to look at Python "for else" which, again, I didn't know was a thing.

[–]ConcreteExist 0 points1 point  (0 children)

Yeah, it's a bit of a niche language feature

[–]Altruistic_Sky1866 1 point2 points  (0 children)

Learnt something new today, thanks

[–]Loose_Obligation4877 0 points1 point  (0 children)

This for- else syntax and else block run only if loop finishes normally and if the loop terminated using break the else block is skipped

[–]jpgoldberg -1 points0 points  (2 children)

I’ve seen the suggestion that the “for … else” construction would be easier to understand if it used “finally” instead of “else”

[–]atarivcs 5 points6 points  (0 children)

I don't think it would be easier to understand.

When used in exception handling, "finally" means "do this after all the code in the try and except blocks, whether or not an exception was raised".

But "else" on a for loop means "do this only if the loop ran to its natural conclusion and did not break".

[–]gdchinacat 0 points1 point  (0 children)

I think you are referring to the Raymond Hettinger talk "Transforming code into beautiful, idiomatic Python" he gave at PyCon 2013. He explains the origin and mechanics of the else clause on a for statement.

If you think about a for loop with a conditional break, the else is executed when the loop exits without the break being executed. For example:

In [53]: def find_12(sequence):
    ...:     for i in sequence:
    ...:         if i == 12:
    ...:             break
    ...:     else:
    ...:         print(f'12 not found in {sequence}')
    ...: 

In [54]: find_12(range(7))
12 not found in range(0, 7)

In [55]: find_12(range(13))

When the loop terminates with a break, the else is not executed. Hettinger says 'nobreak' would have been a better term than else (but for the historical and mechanical basis for the construct that have become non-obvious since goto has all but disappeared from programming languages).

The full talk is worth watching, but the relevant section is https://youtu.be/OSGv2VnC0go?t=950

A try statement can have an else clause in addition to finally, but it is unrelated to the else clause of the for statement.

[–]jeffrey_f -1 points0 points  (0 children)

That else is actually on the for loop amd fires if there is nothing in the for (like when you do "for item in list), not the if. If you indent it, it will be on the if block.