for / while else doesn't make sense

Steven D'Aprano steve at pearwood.info
Thu May 19 20:06:12 EDT 2016


On Fri, 20 May 2016 03:55 am, Jon Ribbens wrote:

> I guess we should thank our lucky stars that you don't have a time
> machine then, since that change would very much be one for the worse
> in my opinion. for...else is perfectly straightforward and clearly
> the right keywords to use. for...then would be entirely wrong.

"Entirely" wrong? "Clearly" the right keyword? "Perfectly" straightforward?

They are extremely strong words given the posts where *even the defenders*
of "else" have admitted that it is a hard keyword to understand. But that's
okay. Maybe you've thought of something the rest of us haven't, and have an
entire consistent mental model of for...else that is easy to understand and
makes it "perfectly straightforward and clearly the right keyword".

Can you explain your model which makes "else" appropriate?

In my experience, some people (including me) misunderstand "for...else" to
mean that the else block runs if the for block *doesn't*. It took me the
longest time to understand why this didn't work as I expected:

for x in seq:
    pass
else:
    print("seq is empty")

because like many people, my mental model was "the for block runs, OR ELSE
the else block runs". This *incorrect* model seems like it works: if you
set seq=[], say, it prints "seq is empty" as expected.

But its wrong: set seq=[1, 2, 3], and it *still* prints "seq is empty". My
model of what was going on was faulty.

I never would have thought of that model if it had been called "then":

for x in seq:
    pass
then:
    print("executes after the for block completes")

which describes what actually happens: regardless of whether seq is empty or
not, the loop runs, THEN the "else" block unconditionally executes. That
has the advantage of also matching the implementation, both as byte-code,
and in C.

I've seen people assume that the for loop actually sets a hidden flag to
record whether or not a break was executed. There is no flag. It simply
doesn't get executed because code execution jumps past it.

But please do explain your execution model of "for...else". If it is better
than mine, I'll be happy to use it instead.



-- 
Steven




More information about the Python-list mailing list