[Python-ideas] Control Flow - Never Executed Loop Body

Terry Reedy tjreedy at udel.edu
Tue Mar 22 14:49:44 EDT 2016


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



More information about the Python-ideas mailing list