for-else

C

castironpi

The idea of the if-else is:
.  depending on some condition either do this or do something else,
.  don't do them both.

yes = the loop completed.

'else' isn't rechecking a piece of the loop, it's checking the loop.
Does it test successfully--- not the loop condition, the loop? What
is 'if a loop'? Make sense, I hold it does. (Holding is good--
something I can drop and give to someone else.) If 'else' gets hit, I
didn't do the loop.
 
T

Terry Reedy

| However the loop-else really works more like this:
| . try to do the loop;
| . if it starts but is interrupted by a break,
| . then do something else as well.

This is NOT how loop-else works for Python.
If you want to do something special on breaks,
put the break-only code before the break.

while loop_condition:
<loop statements>
if break_condition:
<break-only statements>
break
<more loop stuff>

| So they are completely different beasts, and if you try to use
| or explain the one according to the rules of the other one,
| you put a serious strain on your synapses.

I did not mean to broke your brain.

| The explanation that the if-else and the loop-else
| follow the same pattern, runs more or less like this:
| . all conditions to run the loop to its completion were met,
| . which means that the loop-condition is not met (any more),
| . which means that we must do something else.
| For me that is orwellian logic: success is failure.

I gave a clear and coherent explanation of how while derives from if,
and correspondingly, how while-else derives from if-else, to help those who
want to read and write Python code. Building on the pseudo-snippet above,
one can write

while loop_condition:
<loop statements>
if break_condition:
<break-only statements>
break
<more loop stuff>
else:
<completion-only statements>

Python allows one to have both break-only and completion-only sections
together in one compound statement and *without* having to fiddle with a
special flag variable. I am sorry if you cannot appreciate such elegance
and can only spit on it as 'orwellian'.

If the sense of else were reversed, one would have to write the clumbsier

complete = True # though false at this point
while loop_condition:
<loop statements>
if break_condition:
complete = False
break
<more loop stuff>
else:
<break-only statements>
if complete:
<completion-only statements>

Terry Jan Reedy
 
C

Carl Banks

I gave a clear and coherent explanation of how while derives from if,
and correspondingly, how while-else derives from if-else, to help those who
want to read and write Python code. Building on the pseudo-snippet above,
one can write

while loop_condition:
<loop statements>
if break_condition:
<break-only statements>
break
<more loop stuff>
else:
<completion-only statements>

Python allows one to have both break-only and completion-only sections
together in one compound statement and *without* having to fiddle with a
special flag variable. I am sorry if you cannot appreciate such elegance
and can only spit on it as 'orwellian'.


Just to play Devil's advocate, there is one draw drawback to "such
elegance": when there are multiple break statements. Which means
you'd have to duplicate the break-only condition, or refactor somehow
(which may or may not be suitable).

There have been a couple occasions where I felt the best solution was
to a temporary varible like so:

completed = False
while loop_condition:
<loop statements>
if break_condition:
break
<more loop stuff>
if some_other_break_condition:
break
<more loop stuff>
else:
completed = False
if not completed:
<break-only statements>

It felt icky but we're all still here so it couldn't have been that
bad.


Carl Banks
 
R

rockingred

| However the loop-else really works more like this:
| .  try to do the loop;
| .  if it starts but is interrupted by a break,
| .  then do something else as well.

This is NOT how loop-else works for Python.
If you want to do something special on breaks,
put the break-only code before the break.

while loop_condition:
  <loop statements>
  if break_condition:
    <break-only statements>
    break
  <more loop stuff>

| So they are completely different beasts, and if you try to use
| or explain the one according to the rules of the other one,
| you put a serious strain on your synapses.

I did not mean to broke your brain.

| The explanation that the if-else and the loop-else
| follow the same pattern, runs more or less like this:
| .  all conditions to run the loop to its completion were met,
| .  which means that the loop-condition is not met (any more),
| .  which means that we must do something else.
| For me that is orwellian logic: success is failure.

I gave a clear and coherent explanation of how while derives from if,
and correspondingly, how while-else derives from if-else, to help those who
want to read and write Python code.  Building on the pseudo-snippet above,
one can write

while loop_condition:
  <loop statements>
  if break_condition:
    <break-only statements>
    break
  <more loop stuff>
else:
  <completion-only statements>

Python allows one to have both break-only and completion-only sections
together in one compound statement and *without* having to fiddle with a
special flag variable.  I am sorry if you cannot appreciate such elegance
and can only spit on it as 'orwellian'.

If the sense of else were reversed, one would have to write the clumbsier

complete = True # though false at this point
while loop_condition:
  <loop statements>
  if break_condition:
    complete = False
    break
  <more loop stuff>
else:
  <break-only statements>
if complete:
  <completion-only statements>

Terry Jan Reedy

Terry, instead of using "complete = True" and setting it to false on
failure, why not set "loop_completed = False" and set it to True if
the break condition is met?
 
J

Jeffrey Barish

egbert said:
The idea of the if-else is:
.  depending on some condition either do this or do something else,
.  don't do them both.

Indubitably, this statement is correct for other programming languages. I
was initially surprised by loop-else when learning Python because I
approached these constructs from the perspective of other programming
languages I knew, as you are doing. Before rejecting the Python
constructs, I asked myself whether the application of a different idea
resulted in a consistent, sensible interpretation. The key is to ask not
whether the Python constructs fit a particular idea of if-else and
loop-else, but whether a reasonable idea exists within which the Python
constructs make sense. For me and others in this thread, it does.
Different keywords would, no doubt, result in constructs that fit other
ideas better, but personally I am content with the current solution.
 
C

castironpi

The idea of the if-else is:
constructs, I asked myself whether the application of a different idea
resulted in a consistent, sensible interpretation.

They could just as easily have defined the else of a 'for' to mean 'if
the loop only completed not an even number of times', giving these
different outputs:

for a in [1,2,3,4,5]:
if a> 3:
break
else:
print( 'bogus' )

for b in [1,2,3,4,5]:
if b> 4:
break
else:
print( 'foo' )

Just as easily, yes. Just as well? Just as meaningfully? Just as
consistently, usefully, and sensibly?

Possibly. The meaning of 'if a loop' could be construed to mean a
parity test or a binary test (if it didn't even complete once, i.p. if
the sequence was empty). If I tell you to do a loop, and then asked
if you did it, what factors in to your answer?

The docs say, 'A break statement executed in the first suite
terminates the loop without executing the else clause's suite', for
both for- and while-.

Does for-and and while-and or for-ifso and while-ifso sound more to
your liking?
 
T

Terry Reedy

If the sense of else were reversed, one would have to write the clumbsier

complete = True # though false at this point
while loop_condition:
<loop statements>
if break_condition:
complete = False
break
<more loop stuff>
else:
<break-only statements>
if complete:
<completion-only statements>

Terry Jan Reedy

Terry, instead of using "complete = True" and setting it to false on
failure, why not set "loop_completed = False" and set it to True if
the break condition is met?
[OE not quoting properly]
=====================
Because completion is False when broken? Actually, I am not sure what you
mean without seeing the snippet rewritten. Certainly, one could set
'broken=False' at top (tho not true) and 'broken = True' before breaking
and test for 'not broken' at end, but that is not an improvement.

tjr
 
T

Terry Reedy

| Just to play Devil's advocate, there is one draw drawback to "such
| elegance": when there are multiple break statements. Which means
| you'd have to duplicate the break-only condition, or refactor somehow
| (which may or may not be suitable).

Yes, I knowingly glided over the possibility of multiple break statements
with common break-only code and no completion-only code (other than
artifactual flag setting as in your code below ;-). I presume that that
triple condition is even rarer than simpler situations where one of those
conditions is false.

| There have been a couple occasions where I felt the best solution was
| to a temporary varible like so:

But I will accept your testimony that the set of such use cases is not
empty.

| completed = False
| while loop_condition:
| <loop statements>
| if break_condition:
| break
| <more loop stuff>
| if some_other_break_condition:
| break
| <more loop stuff>
| else:
| completed = False

I presume you meant True

| if not completed:
| <break-only statements>
|
| It felt icky but we're all still here so it couldn't have been that
| bad.

tjr
 
N

NickC

The meaning is explicit. While "else" seems to mean little there.
So I may like something similar for Python 3.x (or the removal of the
"else").

Consider a loop with the following form:

while 1:
if <while-cond>:
<0-to-many times code block>
else:
<0-to-1 times code block>
break

A break, return or exception in the 0-to-many times code block will
obviously skip over the 'else' part of that if statement - it will
only be executed if <while-cond> evaluates as a false value. The above
code is actually equivalent to a normal Python while-loop:

while <while-cond>:
<0-to-many times code block>
else:
<0-to-1 times code block>

For loops aren't quite so straightforward since the termination
condition is tied up with the StopIteration exception, but the clause
keeps the same name as the corresponding clause on the while loop.
Thinking of it as break-else (as someone else posted) probably isn't a
bad way to look at the situation.

Cheers,
Nick.
 
C

castironpi

Consider a loop with the following form:

while 1:
  if <while-cond>:
    <0-to-many times code block>
  else:
    <0-to-1 times code block>
    break

A break, return or exception in the 0-to-many times code block will
obviously skip over the 'else' part of that if statement - it will
only be executed if <while-cond> evaluates as a false value. The above
code is actually equivalent to a normal Python while-loop:

while <while-cond>:
  <0-to-many times code block>
else:
  <0-to-1 times code block>

For loops aren't quite so straightforward since the termination
condition is tied up with the StopIteration exception, but the clause
keeps the same name as the corresponding clause on the while loop.
Thinking of it as break-else (as someone else posted) probably isn't a
bad way to look at the situation.

Cheers,
Nick.

Here's what try: else: says. "when control flows off the end of the
try clause." So at least their usage is consistent, even if
pessimistic. They might be using, "2. in addition to the persons or
things mentioned or implied: Who else was there?" - dictionary.com.

But conflate with 'if-else', the if and else are mutually exclusive.
Maybe the if-else should be if-orelse. One's a misnomer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,270
Messages
2,571,341
Members
48,031
Latest member
rashmi16

Latest Threads

Top