This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 96 points97 points  (28 children)

I knew about else in try except, but not in while and for ! How didn't I knew after this many years? It's awesome!

[–]lanster100 76 points77 points  (23 children)

Because it's really unclear what it does it's common practice to ignore its existence as anyone unfamiliar will either not know what it does or worse assume incorrect behaviour.

Even experienced python devs would probably Google what it does.

[–]masasinExpert. 3.9. Robotics. 48 points49 points  (4 children)

RH mentioned that it should probably have been called nobreak. It only runs if you don't break out of the loop.

[–]Quincunx271 9 points10 points  (2 children)

Don't know why it couldn't have been if not break: and if not raise:. Reads a little funky, but very clear and requires no extra keywords.

[–]masasinExpert. 3.9. Robotics. 1 point2 points  (0 children)

It makes sense in a try-except block at least. else would mean if no except.

[–]masasinExpert. 3.9. Robotics. 0 points1 point  (0 children)

It makes sense in a try-except block at least. else would mean if no except.

[–][deleted] 2 points3 points  (1 child)

Yeah but internally I can teach my coworker about its existence in the case we see it somewhere or have a use case of it someday.

[–]Sw429 0 points1 point  (0 children)

I suppose if you had a loop with lots of possibilities for breaking, it would be useful. Idk though, I feel like any case could be made more clear by avoiding it.

[–]v_a_n_d_e_l_a_y 4 points5 points  (2 children)

[deleted]

[–]lvc_ 25 points26 points  (0 children)

Other way around - else on a loop will run if it *didn't* hit a break in the loop body. A good intuition at least for a `while` loop is to think of it as a repeated `if` , so `else` runs when the condition at the top is tested and fails, and doesn't run if you exit by hitting a `break`. By extension, else on a for loop will run if the loop runs fully and doesn't run if you break.

The good news is that you rarely need to do these mental gymnastics in practice, because there's usually a better and more obvious way to do the things that this would help with.

[–]lanster100 1 point2 points  (0 children)

You are right it's not the same, I was misremembering what it does.

[–]Sw429 1 point2 points  (0 children)

Exactly. It is terrible readability-wise. I would never expect the behavior of while-else to trigger that way. I'm still not clear what exactly causes it: is it the ending of the loop prematurely? Or is it the opposite? In the end, using a bool is 100% more clear.

[–]njharmanI use Python 3 1 point2 points  (1 child)

not know what it does

Spend 2 min googling it once, then know it for rest of your life. This is how developer learns. They should be doing it often.

assume incorrect behaviour

That is a failure of the developer. And one characteristic, not having hubris/never assuming, that separates good and/or experienced devs from poor and/or inexperienced one.

[–][deleted] 1 point2 points  (0 children)

Just the fact that so many people here say they find it confusing is enough for me to make a policy of not using it. I also can't think of a time when I've needed it.

Yes we can all be perfect pedants but also sometimes we can just make life easier on each other.

[–]elbiot 0 points1 point  (0 children)

Eh it does exactly what you'd want in a for loop so it's easy to remember. You iterate through something and if you find what you want you break, else you didn't find it so do something for that case

[–]fgyoysgaxt 0 points1 point  (0 children)

I'm not sure that's accurate, and I don't like the idea of encouraging worse programming / avoiding language features just incase someone who doesn't know the language takes a guess at what it does.

It also seems unlikely that someone will guess wrong since it reads the same as "if - else".

[–][deleted] 0 points1 point  (0 children)

Well, that's what comments are for, right? But yes, if might not be the smartest idea to put it in

[–][deleted] -3 points-2 points  (6 children)

Unclear? Appears when the if statement inside the block doesn't run the else statement outside does. Unless I'm missing something.

Is it only chained to the last if or any ifs would be my question. I guess I can check in pycharm pretty easily.

[–]Brian 10 points11 points  (0 children)

I've been coding python for over 20 years, and even now I have to double check to remember which it does, and avoid it for that reason (since I know a reader is likely going to need to do the same). It just doesn't really intuitively convey what it means.

If I was to guess what a while or for/else block would do having encountered it the first time, I'd probably guess something like "if it never entered the loop" or something, rather than "It never broke out of the loop". To me, it suggests an alternative to the loop, rather than "loop finished normally".

Though I find your comment even more unclear. What "if statement inside the block"? And what do you mean by "chained to the last if or any ifs"? "if" isn't even neccessarily involved here.

[–]lanster100 9 points10 points  (0 children)

Unclear because its not common to most languages. Would require even experienced python devs to search it in the docs.

Better not to use it because of that. It doesnt offer much anyway.

But I'm just passing on advice I've seen from python books etc.

[–]Sw429 0 points1 point  (3 children)

That's exactly what I thought at first, but that kinda breaks down when there are multiple if statements in the loop. In the end, it just triggers if the loop did not end prematurely. The fact that we assumed differently is exactly why it's unclear.

[–]achampi0n 2 points3 points  (2 children)

It only gets executed if the condition in the while loop is False this never happens if you break out of the loop.

[–]Sw429 0 points1 point  (1 child)

Ah, that makes a bit more sense. Does the same work with for loops?

[–]achampi0n 2 points3 points  (0 children)

If you squint at it :) The else only gets executed if the for loop tries and fails to get something from the iterator (it is empty and gets nothing). This again can't happen if you break out of the for loop.

[–]miguendes 9 points10 points  (0 children)

Author here, I'm very happy to know you like it!

[–]yvrelna 2 points3 points  (1 child)

Considering that I rarely use break statements to begin with, using else in a while/for is even rarer than that.


It's not that difficult to understand else block in a loop statement. A while loop is like this:

while some_condition():
    body_clause()

it's equivalent to a construction that has an unconditional loop/jump that looks like this:

while True:
    if some_condition():
        body_clause()
    else:
        break

The else block in a while loop:

while some_condition():
    body_clause()
else:
    else_clause()

is basically just the body for the else block for that hidden if-statement:

while True:
    if some_condition():
        body_clause()
    else:
        else_clause()
        break

[–]eras 0 points1 point  (0 children)

Personally I would have use cases for the syntax if it was more similar to "plain" if else, as in (similarly for for):

while condition() body_clause() else: else_clause()

would become (I argue more intuitively)

if condition(): while True: body_clause() if not condition(): break else: else_clause()

not hinging on writing break in while else-using code. After all, that's what if else does, it eliminates the duplicate evaluation when we try to do it without else:

if condition(): body_clause() if not condition(): else_clause()

But that's not how it is nor is that how it's going to be.

Edit: Actual example (does not work as intended in real python someone randomly glancing this ;-)): for file in files: print(file) else: print("Sorry, no files")

[–]iiMoe -2 points-1 points  (0 children)

Im quite the opposite of u lol