Breaking out of nested loops

Bengt Richter bokr at
Sun Jan 13 06:53:31 CET 2002

On Sat, 12 Jan 2002 20:18:19 -0500 (EST), Steven Majewski <sdm7g at Virginia.EDU> wrote:
>However, after trying out an example with multilevel nesting,
>I see that, although it works fine, it does appear a bit awkward
>in Python:
># --------------------------
>class Break1(Exception): pass
>class Break2(Exception): pass
>class Break3(Exception): pass
>from random import randint
>tab = '  '
>def btest():
>  try:
>    while 1:
>      print 'While1'
>      try: ##
>        while 2:
>          print tab,'While2'
>          try:
>            while 3:
>              print tab*2,'While3'
>              for i in range(30):
>                 r = randint(0,6)
>                 print tab*3,'r=',r
>                 if r == 1: raise Break1
>                 elif r == 2: raise Break2
>                 elif r == 3: raise Break3
>          except Break3:
>            print tab*2,Break3
>      except Break2:
>        print tab,Break2
>  except Break1:
>    print Break1
>for test in (1,2,3):
>	print 'test',test
>	btest()
>I admit, it's not simple to follow the control thru all of the
>extra try/excepts and indentation. However, since the exceptions
>do work across function boundaries, if you break it up into
>nested functions (that then still raise exceptions) it's easier
>to follow.
>But then, I'm not sure that adding something like named blocks would
>be any more readable. You would still need an extra level of nesting,
>but the lack of an 'except' would make it more difficult to spot
>the point it breaks out to. And having to count levels for a syntax
>like "break 3" would be even worse.
>( Although, I find named blocks in Lisp OK, but you're more free
>  to use the indentation to make the flow more clear. )
>That conclusion tends to reinforce my initial reaction to these
>proposals: that the 'problem' is really that deeply nested loops
>in a single procedure is the real 'design error' , not any particular
>syntax. Sometimes it can't be avoided, but I haven't seen a proposal
>for new syntax that is any easier to read than the example above.
How about using a dedent-level marker on the next line after the break,
e.g., a lone ':' ? Then the eye can just drop down to where it's going.

def btest():
    while 1:
        print 'While1'
        while 2:
            print tab,'While2'
            while 3:
                print tab*2,'While3'
                for i in range(30):
                     r = randint(0,6)
                     print tab*3,'r=',r
                     if r == 1:   break
                     elif r == 2: break
                     elif r == 3: break
            print tab*2,Break3
        print tab,Break2
    print Break1

for test in (1,2,3):
	print 'test',test

More information about the Python-list mailing list