[Python-Dev] [Python-checkins] cpython (3.2): Nudge readers towards a more accurate mental model for loop else clauses

Stephen J. Turnbull stephen at xemacs.org
Fri Jun 8 09:29:29 CEST 2012


Note: reply-to set to python-ideas.

Nick Coghlan writes:

 > The inaccuracies in the analogy are why this is in the tutorial, not the
 > language reference. All 3 else clauses are really their own thing.

Nick, for the purpose of the tutorial, actually there are 4 else
clauses: you need to distinguish *while* from *for*.  It was much
easier for me to get confused about *for*.  I think Terry is on to
something here:

 > > "An else clause used with a loop has two differences from an else
 > > clause used with an if statement. [...] [The] condition is
 > > tested repeatedly instead of just once. A loop else is the same
 > > in that it triggers when that one condition is false."

I think it would be a good idea to use an example where the loop is a
*while* loop, not a *for* loop.  In the case of the *for* loop, it's
easy to confuse the implicit test used (ie, "item is true") with a
test on the iterable ("iterable is not empty").  With a *while* loop,
that's not true.  I don't have trouble understanding that the while
suite is executed "while" the condition is true:

>>> for n in range(2, 10):
...     x = 2
...     while x < n:
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...         x = x + 1
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...

Of course it's useful to point out here that use of a while loop is
bad style, and the "for x in range(2,n)" version is preferred, having
*exactly the same semantics* for the *else* clause.

Also, I find rewriting the if/else as

    if condition:
        do_when_true()
    else:
        do_when_false()

as

    while condition:
        do_when_true()
        break             # do only once, and skip else!
    else:
        do_when_false()

to be quite mnemonic for understanding what the while/else construct
really does.

 > > [The loop *else*] is subordinate to just one condition instead of
 > > possibly many. (In for statements, the condition is implicit but
 > > still there.)

FWIW, this issue doesn't affect my understanding, as I think of
if/elif/else as "indentation-optimized tail-nested" ifs anyway.

I'm not sure if anybody else will feel as I do, so I don't offer a
patch here.



More information about the Python-Dev mailing list