Live data from Hacker News

The optional “else” in Python loops

shahriar.svbtle.com

21–30 of 50 posts

Re: The optional “else” in Python loops

#22
post #18

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

They are intuitive and very easy to understand and read the code.

If you use Python you should code in Python, not trying to translate C to Python.

Re: The optional “else” in Python loops

#23
post #2

While 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.)

I totally agree. I wrote Python code professionally for five years and am shocked to find I was wrong about this all this time. I must have introduced quite a few bugs. :-/

Re: The optional “else” in Python loops

#24
post #7
post #2

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

I think the real issue is that the word 'else' is ambiguous in the context. Everyone comes in with a different idea of what the 'else' is a fallback clause to. Guido obviously picked one particular case, but there are other valid meanings.

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:
    pass

Re: The optional “else” in Python loops

#25
post #2

While 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's more, it dances very close to something that is a super-common error for novice programmers: the early return from a loop. I grade AP exams every year, and one of the hands-down most common conceptual mistakes I've seen (on problems where this is relevant) goes something like this:

    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 false

Re: The optional “else” in Python loops

#26
post #15

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

> There will always be non-expert programmers of many languages. Avoiding language-specific constructs will not solve the issue.

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
For 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

Re: The optional “else” in Python loops

#28
post #10
post #2

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

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

#29
post #28
post #10

Earlier 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?

finally blocks are always executed; this kind of else block is only executed if the for block exited normally (i.e. did not throw an exception).

Re: The optional “else” in Python loops

#30
post #27

For 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

try/except/else used to throw me, but I've grown to like the idiom.

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.

Post reply on HN