Raymond Hettinger, one of the main Python devs, advises that the "else" in this situation should mentally be thought of as "notfound".
The optional “else” in Python loops
21–30 of 50 posts
Re: The optional “else” in Python loops
#22This is all in Jeff Knupp's Writing Idiomatic Python: http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-p... Many so-called Python Idioms are really non-intuitive and I don't really appreciate.
If you use Python you should code in Python, not trying to translate C to Python.
Re: The optional “else” in Python loops
#23While in theory this is useful, it's one of the least intuitive parts of python for me. I avoid them whenever possible because I feel "else" conveys the intent very poorly. (And I've been writing python for years.)
Re: The optional “else” in Python loops
#24While in theory this is useful, it's one of the least intuitive parts of python for me. I avoid them whenever possible because I feel "else" conveys the intent very poorly. (And I've been writing python for years.)
What finally made it intuitive for me: assuming the loop contains an if condition: break, you can consider the else-clause to be the else of the if statement within the loop.
For example, I think that it's more common to want to do something like:
# mnemonic:
# for thing in list_of_things DO_SOMETHING else DO_SOMETHING_ELSE
if list_of_things:
for thing in list_of_things:
print thing
else:
print "No things!"
Than: for thing in list_of_things:
if thing.is_awesome:
break
else:
print "No awesome things!"
And what about conditional code that you want to execute when a loop does break early? error_found = False
for thing in list_of_things:
if thing.error_condition:
error_found = True
break
if error_found:
passRe: The optional “else” in Python loops
#25While in theory this is useful, it's one of the least intuitive parts of python for me. I avoid them whenever possible because I feel "else" conveys the intent very poorly. (And I've been writing python for years.)
boolean lookForSomething(int parameter) {
for (Item item: list) {
if (item.matches(parameter))
return true;
else
return false;
}
}
where a correct answer would omit the "else" and put the "return false;" outside the bracketed loop (or, keep a boolean variable updated and then return that after the loop is done. Let's translate that to python: def lookForSomething(parameter):
for item in list:
if matches(item, parameter):
return true
else:
return false
As a conceptual matter, for a beginner who is still trying to nail down the whole notion of "can stop early when found, but have to scan the whole list if not found", it is just plain nasty that the following code is not only correct but idiomatic: def lookForSomething(parameter):
for item in list:
if matches(item, parameter):
return true
else:
return falseRe: The optional “else” in Python loops
#26I always strongly discourage the use of things like this construct in any language. A language is meant to be read not just written. A non-expert python programmer who encounters this will be confused.
There will always be non-expert programmers of many languages. Avoiding language-specific constructs will not solve the issue. As far as portability is concerned (if you port software by hand a lot, for example), this is indeed an issue; but if you work with people who write python code, you might as well use everything in your toolbox.
This is a language-specific issue that occurs rarely in the wild. Yes, it's part of the language, but it's used rarely enough that it can trip up even experienced Python programmers.
For example, Perl (until more recently) allowed one to change arrays to be 1-indexed, rather than 0-indexed at runtime. Just because it's part of the language doesn't mean that it's a good thing to use it.
Re: The optional “else” in Python loops
#27 try:
None.doit()
except Exception as e:
logger.exception('Nope')
else:
# now what?
passRe: The optional “else” in Python loops
#28While in theory this is useful, it's one of the least intuitive parts of python for me. I avoid them whenever possible because I feel "else" conveys the intent very poorly. (And I've been writing python for years.)
Raymond Hettinger has suggested that instead of `else:` the keyword should have been called `nobreak:` which conveys intentions better.
Re: The optional “else” in Python loops
#29Earlier quoted context omitted.
Raymond Hettinger has suggested that instead of `else:` the keyword should have been called `nobreak:` which conveys intentions better.
What about using "finally," which if IIRC is already a thing in Python and encapsulates this idea pretty neatly?
Re: The optional “else” in Python loops
#30For me, the optional else on for loops isn't nearly as mentally destabilizing as the optional else on try-except blocks. An ex-employee used to love doing that: try: None.doit() except Exception as e: logger.exception('Nope') else: # now what? pass
All it means is the try clause didn't raise any exceptions. And a "finally" clause is ran whether an exception was raised or not.