fun with nested loops

Daniel dalist0 at gmail.com
Wed Aug 31 11:51:45 EDT 2011


Dear All,

I have some complicated loops of the following form

for c in configurations: # loop 1
    while nothing_bad_happened: # loop 2
        while step1_did_not_work: # loop 3
            for substeps in step1 # loop 4a
                # at this point, we may have to
                -leave loop 1
                -restart loop 4
                -skip a step in loop 4
                -continue on to loop 4b

        while step2_did_not_work: # loop 4b
            for substeps in step2:
                # at this point, we may have to
                -leave loop 1
                -restart loop 2
                -restart loop 4b
                ...
        ...many more loops...


I don't see any way to reduce these nested loops logically, they
describe pretty well what the software has to do.
This is a data acquisition application, so on ever line there is
a lot of IO that might fail or make subsequent steps useless or
require a
retry.

Now every step could need to break out of any of the enclosing loops.
So basically I have to transform every loop to be of the following
horror:

# general transformation of
# "for c in configurations..."
# to provide restart, break and continue
# callable from any nesting level inside of the loop

class loop1_restart(Exception): pass
class loop1_break(Exception): pass
class loop1_continue(Exception): pass

while True:
    try:
        for c in configurations:
            while True:
                try:
                    # inner loops go here, of course, they would have
to get
                    # all the boilerplate added, too
                    while nothing_bad_happened:
                        while step1_did_not_work:
                           if cond1:
                               raise loop1_restart()
                           elif cond3:
                               raise loop1_break()
                           elif cond3:
                               raise loop1_continue()

                    break

                except loop1_continue:
                    pass
        break
    except loop1_restart:
        pass
    except loop1_break:
        break

Of course this is extremely tedious and error prone.
If Python had named loops (PEP 3136, unfortunately rejected), this
would be trivial:
In Fortran I can continue (cycle), break (exit) and redo (goto label)
arbitrary
loops, which results in neat code:

10 loop1: do I=1,3
    loop2: do J=1,4
        print *,I,J
        goto 10
        cycle loop1
        exit loop1
    enddo loop2
enddo loop1


My question is, how do I obtain something that implements the
following logic:

@named_loop(fred) # I wish this would be possible
for i in range(10):
    for j in range(10):
        break fred # breaks out of outer loop
        continue fred # continues outer loop
        redo fred # resets outer loop and restarts with i=0


The best solution would be something along the Proposal D - Explicit
iterators
in PEP 3136, in this case it would even be possible to peek at the
next i or
advance/reverse the iterator a few steps.

Has anyone an idea on a nice way to write breaks/continues/redos for
deeply
nested loops?


Dan





More information about the Python-list mailing list