Breaking/continuing out of multiple loops

But I wouldn’t consider the needing-to-break-from-nested-loops case as an example of this : we don’t choose to separate it from the rest of the code just to make it more understandable, we’re doing it because the syntax gives us no other choice.

Exactly!!

It’s not the ONLY solution. Multiple solutions have repeatedly been given. Are there situations where the current half-dozen solutions aren’t good enough, and that having “only” this handful of solutions is a problem? You have given no such indication.

They are all ways of getting around the problem, not actual solutions presented by the programming language, which should be the case. You either:

  1. need to refactor it into a function, which you would have done already if you wanted to do that for reasons other than achieving this functionality. It also doesn’t provide a way to use multilevel continue and you would need one function for each loop level so that you can return at different points in the loop and not just the outermost like @steven.daprano 's workaround.

  2. need to use things that weren’t meant to be used for this purpose such as a try and except block. If the block was already there, this means you will pollute it by adding an exception (or two for break and continue) that’s not really an exception and make your code harder to understand. If it wasn’t, you will push everything one indent forward and make your code harder to understand at a glance because it will seem like you are catching a real exception but aren’t. On top of it all, this workaround also suffers from the same problem as workaround 1, which is that you need one try-except block at each loop level in order to have full control over the flow.

  3. need to use flag variables, which also add a bunch of unnecessary lines of code as well as useless variables

  4. other horrible solutions that don’t allow for full loop control and/or continue and/or require a bunch of lines of code or refactoring or whatever else

All of these workarounds, which is what they actually are as opposed to actual solutions, have very clear drawbacks. They are forceful and impose redesigns, pollute your code and are not quick to implement or remove.

Named and numbered break/continue have the following advantages:

  • Fine control. At any loop level, you can fully control the flow of any preceding loop
  • Allows for both break and continue
  • Extremely quick to implement and remove from code
  • Clear, unambiguous and concise. Does not increase the indent level
  • Is not a makeshift, jury-rigged workaround and does not force you to change your code in any way
  • Not ONE single line of code is added

The fact that multiple other languages have implemented this functionality proves beyond any doubt that there is demand for it. Even 15 years ago, when Guido originally rejected it, he said it had already been brought up several times. He argued:

… before you know it you have an incredible mess on your hands of unintelligible code.

I think it’s abundantly obvious that the alternatives are what actually lead to messy, unintelligible code. This can be clearly seen because:

  1. They require many more characters and several more lines of code as opposed to a single integer or “as [loop_name]” added to a line that already existed
  2. They raise the indent level, particularly if, for some reason, you need to control the loop flow at more than one loop level
  3. They use Python functionality that wasn’t really meant to be used for such purposes
  4. They force you to refactor your code in ways you didn’t want to
  5. They invariably involve adding more variables, if clauses, etc. making your code more polluted and harder to read

I honestly can’t think of a single real advantage these solutions have over labeled or numbered breaks.