fun with nested loops
aspineux
aspineux at gmail.com
Wed Aug 31 12:35:45 EDT 2011
On Aug 31, 5:51 pm, Daniel <dali... at gmail.com> wrote:
> 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?
Hi Dan, it looks like you have already answered all your questions.
one more idea, a kind of named loop:
ic=0
op='what to do'
while ic<len(configurations):
c=configuration[ic]
if op=='restart':
ic=0
elif op=='next'
ic+=1
elif op=='terminate'
ic=len(configurations)
and at first explicit iterator was also a good idea, when you don't
need to iter in reverse order
When it become too complicate, I use state machine:
http://en.wikipedia.org/wiki/Finite-state_machine
Regards
>
> Dan
More information about the Python-list
mailing list