TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python’s For - Else

469 pointsby federicoponzialmost 7 years ago

35 comments

askvictoralmost 7 years ago
The word else implies something different to what it does (IMHO at least). In and if&#x2F;else clause, the else happens when the primary&#x2F;expected thing doesn&#x27;t happen. I would expect that for a loop, an else clause would happen when the loop does _not_ finish normally, or if they loop is empty. I&#x27;m sure it&#x27;s a useful clause in certain cases, but the meaning of the word used is reversed. It might be better use &#x27;then&#x27; or something like that:<p><pre><code> for i in l: print(i) then: print(&quot;iteration finished without breaking&quot;)</code></pre>
评论 #17170561 未加载
评论 #17169907 未加载
评论 #17169742 未加载
评论 #17170397 未加载
评论 #17170421 未加载
评论 #17169783 未加载
评论 #17170001 未加载
评论 #17170500 未加载
评论 #17170136 未加载
评论 #17170165 未加载
评论 #17170022 未加载
评论 #17169788 未加载
评论 #17169727 未加载
评论 #17171058 未加载
评论 #17170044 未加载
评论 #17171767 未加载
评论 #17170079 未加载
评论 #17170738 未加载
评论 #17177134 未加载
reuvenalmost 7 years ago
I love Python&#x27;s for-else feature. I&#x27;ve used it on a number of occasions, and have found it to be useful and to cut down on code.<p>However, I agree that the use of &quot;else&quot; is horribly confusing. When I teach &quot;for-else&quot; to students in my Python courses, they are often surprised by the functionality, and doubly surprised that the word &quot;else&quot; is used. I often joke that it would be a great feature, if only they had chosen something a bit more intuitive and memorable instead of &quot;else&quot;, such as &quot;if_we_exited_the_block_without_encountering_a_break&quot;. Slightly more seriously: While I realize that adding a keyword to Python isn&#x27;t in the cards, a word such as &quot;nobreak&quot; would be easier for people to understand, and would stress the point of the functionality.<p>The fact that Emacs always tries to indent the &quot;else&quot; of a &quot;for-else&quot; to align with an &quot;if&quot; inside of the loop, rather than the &quot;for&quot; with which it matches, speaks volumes. I mean, if Emacs is confused, then how are we mere mortals supposed to remember?<p>So when I use &quot;for-else&quot;, it&#x27;s almost always in code that I am writing for myself, and that I don&#x27;t expect others to read or maintain.<p>Don&#x27;t forget that there&#x27;s also &quot;while-else&quot;, although I can&#x27;t remember the last time I saw that actually used.
评论 #17171393 未加载
评论 #17171973 未加载
mixmastamykalmost 7 years ago
Yes the for...else is useful but for years it didn&#x27;t do what I expected, which is execute when the sequence was empty. After reading the docs a half dozen times I finally internalized that the else actually means &quot;not broken,&quot; aka &quot;not found.&quot;<p>So now when I use it, I always put a comment next to it for myself and the next person:<p><pre><code> for item in items: if found: break else: # no-break print(&#x27;not found.&#x27;)</code></pre>
评论 #17170220 未加载
评论 #17169901 未加载
评论 #17169835 未加载
评论 #17171110 未加载
评论 #17169767 未加载
nickm12almost 7 years ago
<a href="https:&#x2F;&#x2F;twitpic.com&#x2F;4a52sh" rel="nofollow">https:&#x2F;&#x2F;twitpic.com&#x2F;4a52sh</a><p>A survey on this feature was done at Pycon 2011. Maybe things have changed since then, but at the time, most people didn&#x27;t understand what for&#x2F;else did.<p>I think it&#x27;s a bad construct because, as many have mentioned, a lot of people make the commonsense interpretation that the else block will only execute if the for block did not.<p>Note, the link above come via Jeremy Avnet in the comments of this blog post.<p><a href="https:&#x2F;&#x2F;nedbatchelder.com&#x2F;blog&#x2F;201110&#x2F;forelse.html" rel="nofollow">https:&#x2F;&#x2F;nedbatchelder.com&#x2F;blog&#x2F;201110&#x2F;forelse.html</a>
评论 #17170998 未加载
评论 #17171105 未加载
SmirkingRevengealmost 7 years ago
I&#x27;ve used the loop -&gt; else construct sparingly - there are times when it is really convenient.<p>But it is VERY confusing.<p>Its very confusing, and poor design - IMHO - because the presence of an &quot;else&quot; block, in the typical case, generally indicates that the preceding block was never executed.<p>When it comes to while&#x2F;for blocks in python, the keyword literally indicates the opposite - that the preceding block executed without hiccups - and so also execute this block.<p>Its a great feature - but there should have been another keyword for it: &quot;also&quot; (or something like that)
评论 #17170637 未加载
评论 #17170679 未加载
eigenvaluealmost 7 years ago
The fact that so many commenters here are confused or surprised by what it means or how it works sort of proves to me that it is a bad idea to use this in your code-- especially if anyone else might need to work on that code. I always prefer the clearer, obvious approach, even it is slightly longer.
评论 #17169889 未加载
评论 #17169867 未加载
contravariantalmost 7 years ago
Oh, that didn&#x27;t do what I expected at all.<p>I was expecting this to be similar to:<p><pre><code> if list: for x in list: # Some code else: # else clause </code></pre> which would have been quite useful to have for general iterators. But apparently it&#x27;s a statement that triggers <i>unless</i> you use &#x27;break&#x27; to end the loop, which just seems like a really weird use case, and smells like a goto.
评论 #17169709 未加载
评论 #17169693 未加载
评论 #17169792 未加载
评论 #17170267 未加载
评论 #17169680 未加载
评论 #17172725 未加载
评论 #17169704 未加载
benwilber0almost 7 years ago
I hate adding syntax but you know what&#x27;s really useful? Django&#x27;s `for .. empty` template syntax.<p>I would like to see this in Python:<p><pre><code> for i in []: print(i) empty: print(&quot;Sequence was empty!&quot;)</code></pre>
评论 #17169665 未加载
评论 #17169749 未加载
jacob019almost 7 years ago
I&#x27;ve been using this for years and never thought twice about it, I&#x27;m shocked by all the negativity.<p>It&#x27;s great for controlling iteration in a nested loop:<p><pre><code> for item in report(): for event in in item[&#x27;events&#x27;]: if event in events_we_care_about: break else: continue act_upon(item) </code></pre> I realize it&#x27;s a trivial example that could be written without a nested loop, but there are often good reasons for nested loops and littering them with control variables and if statements gets messy quick. I have always found for-else to produce more elegant code.<p>Your criticisms may be quite valid, I just wanted to share my surprise.
评论 #17170574 未加载
评论 #17172515 未加载
jordansmithnzalmost 7 years ago
To me, the else isn’t intuitive if you haven’t encountered it before. It’s a nice feature, but perhaps better naming could improve code readability.<p>How about for-finally? It’s a hard thing to name correctly, but to me this seems to be slightly more intuitive if you’ve never seen the feature before.
评论 #17169747 未加载
评论 #17169734 未加载
评论 #17169753 未加载
hiccuphippoalmost 7 years ago
I had my first legitimate use of for else last week after knowing about it for years and it (the keyword) never making much sense.<p>I had to call an API for it to load data into a cache, but sometimes this wouldn&#x27;t work so I made it try up to 3 times, otherwise it would show an error. So something like:<p><pre><code> for i in range(3): if load_cache(): log(&quot;success&quot;) break else: log(&quot;failure&quot;) </code></pre> Else made total sense here.
zmmmmmalmost 7 years ago
Nearly everybody seems surprised by what it does, which would appear to constitute a fairly strong violation of the &quot;principle of least surprise&quot; that is one of the most cited guiding principles employed by the designers of Python. As such it would seem better to be described as an &quot;anti-tip&quot; or something like that.
评论 #17170540 未加载
kbumsikalmost 7 years ago
It is worth noting that the else clause can also be used with while loops.<p>[1]: <a href="https:&#x2F;&#x2F;docs.python.org&#x2F;3.6&#x2F;reference&#x2F;compound_stmts.html#while" rel="nofollow">https:&#x2F;&#x2F;docs.python.org&#x2F;3.6&#x2F;reference&#x2F;compound_stmts.html#wh...</a>
评论 #17169752 未加载
评论 #17169574 未加载
评论 #17169553 未加载
makecheckalmost 7 years ago
While this is a great capability to have, the tendency to have an indented “if” preceding a not-indented “else” just always seems like somebody might have made a mistake.<p>I would rather something that captures the loop state itself as an operable object, such as:<p><pre><code> with for as loop: for x in my_list: ... if not loop.broken: ...</code></pre>
评论 #17170601 未加载
评论 #17169994 未加载
评论 #17170934 未加载
评论 #17170568 未加载
m4r71nalmost 7 years ago
One thing that for-else is very useful for is implementing an elegant and easy-to-understand retry mechanism:<p><pre><code> for _ in range(3): success = do_something() if success: break else: raise FailedToDoSomething </code></pre> I generally like this feature of the for loop and it would be a shame if it was removed.
评论 #17171733 未加载
blumomoalmost 7 years ago
I find this pattern very much better expressed with functional programming:<p><pre><code> item = next((item for item in container if search_something(item)), None) if item: process(item) else: not_found_in_container() </code></pre> instead of as suggested in the blog post:<p><pre><code> for item in container: if search_something(item): # Found it! process(item) break else: # Didn&#x27;t find anything.. not_found_in_container()</code></pre>
评论 #17171741 未加载
SamReidHughesalmost 7 years ago
Since Python doesn&#x27;t have goto statements, this removes one of the situations where a goto statement is the best tool to use in a language like C++.
评论 #17170027 未加载
hajderralmost 7 years ago
This is strongly advised against in the book Effective Python as the semantics are opposite to what one is used to. The else clause will always be executed unless there&#x27;s a &#x27;break&#x27; in the for-loop.
marbanalmost 7 years ago
Now I feel like I have to rewrite every single Python script I ever wrote.
评论 #17169686 未加载
评论 #17170081 未加载
pure_ambitionalmost 7 years ago
Well, that’s a dumb feature. Very counterintuitive, requires you to stop and think, and there’s a high probability that it’ll be misunderstood at first glance. I hate things like this - you’ll read it, think you understand it, experience a bug, spend hours debugging, then finally look up the documentation for ‘else’ and see that it means something different from what you thought.
julienfr112almost 7 years ago
I write quite often something like that:<p><pre><code> for i in range(10): for j in range(10): if condition(i,j): dosomething break else: continue break </code></pre> It&#x27;s a pattern that ensure that dosometing is run at most once by &quot;propagating&quot; the break to the outer loop.<p>The alternative is use a function and do a return.<p>Any though of this ?
评论 #17172534 未加载
fratlasalmost 7 years ago
I&#x27;m in favour of writing simple python that even a junior dev can read rather than using niche syntax tricks. Guess that depends on whether you think a junior should know this syntax.
评论 #17169669 未加载
评论 #17169691 未加载
评论 #17169666 未加载
joshmkayalmost 7 years ago
I can&#x27;t see this ever being used. As a non-python programmer, if I ran across this it would be very confusing. If it&#x27;s simple enough to write the same code without the else block and have your code be more readable, why not do that?
OJFordalmost 7 years ago
I much more frequently wish that I could express &#x27;or do this if zero iterations&#x27; than I use for-else as it is; I do so wish it had the former semantic.<p>That and the absence of do-while are the cause of a good deal of non-DRY python around loops.
ageofwantalmost 7 years ago
The `else` clause follows the same general pattern wherever it supported: `for`, `while` and `try` are consistent. It usually makes code shorter or at least leads to narrowing concerns when used with `try`.<p>For some reason I often forget to use it though.
holografixalmost 7 years ago
I would never include this in my code. It’s a construct most devs have never seen in Python and it differs from anything I’ve seen in other languages.<p>Always KISS.
AlexCoventryalmost 7 years ago
I&#x27;m curious why people are interested in this. No way I would have predicted it would get to the top of HN.
nearmusealmost 7 years ago
Or maybe it was a terrible &quot;or else&quot; pun that does not deserve much discussion.
quickthrower2almost 7 years ago
Else is a bit of a confusing name for the keyword IMO.<p>How about &quot;ifcompleted&quot;
rad_gruchalskialmost 7 years ago
Pretty convenient feature.
grosjonaalmost 7 years ago
I hate it when code uses weird niche features that are not obvious, are impossible to look up and add 0 value aside from saving a couple of lines of code.
评论 #17169565 未加载
评论 #17169608 未加载
评论 #17169550 未加载
评论 #17169615 未加载
bjournealmost 7 years ago
This is coincidentally my highest rated Stackoverflow answer ever. :)<p><a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9979970&#x2F;why-does-python-use-else-after-for-and-while-loops" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;9979970&#x2F;why-does-python-...</a><p>Tl;dr my highly opinionated opinion is that one should never use the construct
cup-of-teaalmost 7 years ago
For-else is nothing. The really weird one is the Try-else.<p>The For&#x2F;While-else does exactly what I expect. I&#x27;m not sure why others find it confusing.<p>The Try-else does make some code more readable but is quite rare I would say.
评论 #17170990 未加载
mychaelalmost 7 years ago
Never use this in the real world please.
random_throwalmost 7 years ago
This is discussed as item 12 in Effective Python. The author argues that you should avoid &quot;else&quot; blocks after &quot;for&quot; and &quot;while&quot; loops. The main argument is that the behavior is not intuitive and could be confusing upon reading given its somewhat obscure usage.<p>He suggests using a helper function with an early exit or setting a result variable and using a break in your loop instead.