How to break out of multiple loops?

后端 未结 30 3248
情书的邮戳
情书的邮戳 2020-11-21 05:48

Given the following code (that doesn\'t work):

while True:
    #snip: print out current state
    while True:
        ok = get_input(\"Is this ok? (y/n)\")
          


        
相关标签:
30条回答
  • 2020-11-21 06:14

    My first instinct would be to refactor the nested loop into a function and use return to break out.

    0 讨论(0)
  • 2020-11-21 06:16

    Here's another approach that is short. The disadvantage is that you can only break the outer loop, but sometimes it's exactly what you want.

    for a in xrange(10):
        for b in xrange(20):
            if something(a, b):
                # Break the inner loop...
                break
        else:
            # Continue if the inner loop wasn't broken.
            continue
        # Inner loop was broken, break the outer.
        break
    

    This uses the for / else construct explained at: Why does python use 'else' after for and while loops?

    Key insight: It only seems as if the outer loop always breaks. But if the inner loop doesn't break, the outer loop won't either.

    The continue statement is the magic here. It's in the for-else clause. By definition that happens if there's no inner break. In that situation continue neatly circumvents the outer break.

    0 讨论(0)
  • 2020-11-21 06:17

    In this case, as pointed out by others as well, functional decomposition is the way to go. Code in Python 3:

    def user_confirms():
        while True:
            answer = input("Is this OK? (y/n) ").strip().lower()
            if answer in "yn":
                return answer == "y"
    
    def main():
        while True:
            # do stuff
            if user_confirms():
                break
    
    0 讨论(0)
  • 2020-11-21 06:18

    By using a function:

    def myloop():
        for i in range(1,6,1):  # 1st loop
            print('i:',i)
            for j in range(1,11,2):  # 2nd loop
                print('   i, j:' ,i, j)
                for k in range(1,21,4):  # 3rd loop
                    print('      i,j,k:', i,j,k)
                    if i%3==0 and j%3==0 and k%3==0:
                        return  # getting out of all loops
    
    myloop()
    

    Try running the above codes by commenting out the return as well.

    Without using any function:

    done = False
    for i in range(1,6,1):  # 1st loop
        print('i:', i)
        for j in range(1,11,2):  # 2nd loop
            print('   i, j:' ,i, j)
            for k in range(1,21,4):  # 3rd loop
                print('      i,j,k:', i,j,k)
                if i%3==0 and j%3==0 and k%3==0:
                    done = True
                    break  # breaking from 3rd loop
            if done: break # breaking from 2nd loop
        if done: break     # breaking from 1st loop
    

    Now, run the above codes as is first and then try running by commenting out each line containing break one at a time from the bottom.

    0 讨论(0)
  • 2020-11-21 06:20

    An easy way to turn multiple loops into a single, breakable loop is to use numpy.ndindex

    for i in range(n):
      for j in range(n):
        val = x[i, j]
        break # still inside the outer loop!
    
    for i, j in np.ndindex(n, n):
      val = x[i, j]
      break # you left the only loop there was!
    

    You do have to index into your objects, as opposed to being able to iterate through the values explicitly, but at least in simple cases it seems to be approximately 2-20 times simpler than most of the answers suggested.

    0 讨论(0)
  • 2020-11-21 06:20
    # this version uses a level counter to choose how far to break out
    
    break_levels = 0
    while True:
        # snip: print out current state
        while True:
            ok = get_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y":
                break_levels = 1        # how far nested, excluding this break
                break
            if ok == "n" or ok == "N":
                break                   # normal break
        if break_levels:
            break_levels -= 1
            break                       # pop another level
    if break_levels:
        break_levels -= 1
        break
    
    # ...and so on
    
    0 讨论(0)
提交回复
热议问题