On 3/21/2016 9:29 AM, Steven D'Aprano wrote:
On Sun, Mar 20, 2016 at 11:19:54PM -0400, Terry Reedy wrote:
On 3/20/2016 9:32 PM, Steven D'Aprano wrote:
I understood from the keyword that "else" ran *if the for block didn't*, i.e. when the loop iterator is empty. A perfectly natural mistake to make,
Why is the truth a mistake?
It's not the truth.
Yes it is. When the iterator is empty, possibly after many iterations, and the iterator is tested, the else clause runs.
The else block does *not* only run if the for block doesn't run.
I have never, ever, claimed that. Initially empty and empty after all items have been processed are different.
matches the most common and familiar use of "else", namely in if...else statements:
if ...: a else: b
You can get a, or b, but not both. In English, "else" represents an alternative. This does not come even close to matching the behaviour of for...else, which (in the absense of a "break" executes a *and* b, rather than a *or* b:
Block a may never be executed. In any case, once it is, the loop starts over, the test is repeated, and either a or b is executed.
It's an IF...else statement. There's no loop.
It becomes a while loop when 'go to if-test' is added after 'a'.
for ...: a else: b
I see it differently. For both while and for, block b is the alternative to executing a, when the condition (explicit in 'while', implicit in 'for) is false, just as in an 'if' statement.
That's not what for...else does. Try it with an empty sequence and a non-empty sequence:
for x in [1,2]: print("inside for block") else: print("inside else block")
for x in []: print("inside for block") else: print("inside else block")
BOTH the empty and non-empty cases print "inside else block". It is certainly not "the alternative".
Each time next(iterable) is called by the for loop machinery, executing b is the alternative to executing a. You and I view the overall looping process differently. The way I see it, as repeating if-else whenever if is true, makes 'else' perfectly sensible. You see it differently, in a way that makes 'else' less sensible. Here is an alternative way to construct 'while condition' from if-else. Imagine that we only have a loop-forever primative (implemented internally as an unconditional jump). Python currently spells this as 'while True'. Then 'while condition' could written as the following (which works today). while True: if condition: true_part() else: false_part() break The false_part is the alternative to the true_part. -- Terry Jan Reedy