On Mon, 30 Jan 2017 10:52 am, Erik wrote: > On 29/01/17 14:42, Steve D'Aprano wrote: >> 1. for...else is misspelled, and should be for...then; >> >> 2. Same for while...else; > > I don't think I'll ever agree with you on this one. > > "then", to me, implies the code following it is always executed. > "else" implies it's conditional. > > In those constructs it's conditional and therefore, to me, "else" is a > better reminder of that.
But it isn't conditional. When the code reaches the end of the for/while block, the else block is ALWAYS executed. Unconditionally. The only way to skip the else block is to avoid reaching the end of the for/while block: raise, break or return out of the body of the block. > It would be even better if it was "else if not break:" to make the > meaning clearer. break is not the only way to exit the for loop. > I would agree that it would be even better than that if > it was "then if not break:" (apart from needing the new keyword ;)), as > then the conditional aspect is explicit. But it isn't conditional. Your syntax implies that the interpreter keeps some sort of flag did_we_reach_the_end_of_the_loop_without_break or something, and then it checks the state of that flag. There is no such flag. If I remember correctly, that last time this came up here was because somebody asked how they could read the value of that flag, instead of setting their own: for x in seq: ... if not did_we_reach_the_end_of_the_loop_without_break: print("break") They hoped to use the same flag the for-loop used. But if you use the dis module to decompile the CPython byte-code you will see that there is no such flag. Code like this: for i in seq: break else: foo bar compiles to something like this (results may vary according to the version of Python): py> import dis py> code = compile(""" ... for i in seq: ... break ... else: ... foo ... bar ... """, "", "exec") py> dis.dis(code) 2 0 SETUP_LOOP 19 (to 22) 3 LOAD_NAME 0 (seq) 6 GET_ITER >> 7 FOR_ITER 7 (to 17) 10 STORE_NAME 1 (i) 3 13 BREAK_LOOP 14 JUMP_ABSOLUTE 7 >> 17 POP_BLOCK 5 18 LOAD_NAME 2 (foo) 21 POP_TOP 6 >> 22 LOAD_NAME 3 (bar) 25 POP_TOP 26 LOAD_CONST 0 (None) 29 RETURN_VALUE Not a single condition to be seen, anywhere. Its all unconditional jumps. To anticipate a possible objection: it is possible that the FOR_ITER bytecode is implemented with a conditional test, but even so, all that tests for is whether to enter the main body of the for-loop (10 STORE_NAME ...) or jump to (18 LOAD_NAME ...). If you remove the break completely, or replace it with raise or (in a function) return, and you'll see the same structure to the code: for loops run the main body of the loop, then unconditionally run the else block, then unconditionally exit the loop and continue on with the rest of the program. To avoid the else block, you have to jump out of the entire for-loop. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list