Tutorial :python: exit out of two loops



Question:

  for row in b:      for drug in drug_input:        for brand in brand_names[drug]:  

from the third loop how do i exit the current loop and go to the next value of for row in b: ?


Solution:1

This one uses a boolean to see if you are done yet:

done = False  for x in xs:      for y in ys:          if bad:              done = True              break        if done:          break  

This one will continue if no break was used. The else will be skipped over if there was a break, so it will see the next break. This approach has the benefit of not having to use a variable, but may be harder to read to some.

for x in xs:      for y in ys:          if bad:              break      else:          continue        break  


Solution:2

for row in b:     more_drugs = True     for drug in drug_input:        for brand in brand_names[drug]:            if something:                more_drugs = False                break          if not more_drugs:            break  

Python doesn't have a control structure for breaking from two loops at once, so you need to do something manual like this.


Solution:3

If you have three levels of looping in one method then you probably need to rethink your design.

  • Split your method up into smaller, simpler methods.
  • Use a list comprehension and methods like all and any to avoid writing explicit loops.

Doing either of these should mean that you no longer have this issue.


Solution:4

Exception handling beats setting variables all over the place IMO

for row in b:      for drug in drug_input:          try:              for brand in brand_names[drug]:                  if some_condition:                      raise StopIteration          except StopIteration:              break  


Solution:5

I would consider putting the two inner loops in function and using return from there. Probably rethinking what you are doing and how gives the better alternative to that though.

Could you give your current pseudo code, input and output, so we could try to remove the need for the break in first place? We need to see where the loop variables are used or better still, what is the goal of the processing.


Solution:6

Latest PEP I see requesting this feature is 3136 (and was rejected): http://mail.python.org/pipermail/python-3000/2007-July/008663.html

Closest & cleanest thing I could see to what you want to do would be do the following (and since even type names are scoped, you could declare LocalBreak within the function its needed):

class LocalBreak(Exception): pass    try:     for i in ...:         for h in ...:             for j in ...:                if should_break(j):                   raise LocalBreak()  except LocalBreak:     pass  


Solution:7

Untested:

inner_termination=False  for row in b:      for drug in drug_input:         for brand in brand_names[drug]:             <blah>             if break_condition:                 inner_termination=True                 break              <blah>         if inner_termination:             inner_termination=False             break   


Solution:8

for row in b:      ok = True      for drug in drug_input:          if not ok:              break;          for brand in brand_names[drug]:              if not ok:                  break              if whatever:                  ok = False  


Solution:9

try/except/raise, as suggested in @gddc's comment, is one possibility. Another one is to "wrap up" the two nested loops into one:

for row in b:    for brand in (b for d in drug_input for b in brand_names[d]):      ...  

now, a break from the for brand nested loop will go back to the for row outer loop level. Of course, this works only when the code that is here replaced by ... does not need to see the drug name bound to the drug currently being examined. Is that the case for you?


Solution:10

for a in aa:       for b in bb:           for c in cc:              if c == a[b]:                  break           else:               continue           break  

Python supports for...else statements. else block is evaluated if the inner break is not fired.


Solution:11

If you have too many embedded loops, it might be time for a refactor. In this case, I believe the best refactor is to move your loops into a function and use a return statement. That will force-exit out of any number of loops. For example:

def example(self, drug_input):      ok = False      for x in drug_input["names"]:          for y in range(drug_input["number_of_drugs"]):              for z in drug_input["list_of_drugs"]:                  # do stuff                  if ok:                      return drug_costs  

Now, perhaps reformulating your logic like this is tricky, but I bet the refactoring will help in other ways.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »