How to break out of multiple loops?

后端 未结 30 3321
情书的邮戳
情书的邮戳 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:00

    To break out of multiple nested loops, without refactoring into a function, make use of a "simulated goto statement" with the built-in StopIteration exception:

    try:
        for outer in range(100):
            for inner in range(100):
                if break_early():
                    raise StopIteration
    
    except StopIteration: pass
    

    See this discussion on the use of goto statements for breaking out of nested loops.

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

    I'd like to remind you that functions in Python can be created right in the middle of the code and can access the surrounding variables transparently for reading and with nonlocal or global declaration for writing.

    So you can use a function as a "breakable control structure", defining a place you want to return to:

    def is_prime(number):
    
        foo = bar = number
    
        def return_here():
            nonlocal foo, bar
            init_bar = bar
            while foo > 0:
                bar = init_bar
                while bar >= foo:
                    if foo*bar == number:
                        return
                    bar -= 1
                foo -= 1
    
        return_here()
    
        if foo == 1:
            print(number, 'is prime')
        else:
            print(number, '=', bar, '*', foo)
    

    >>> is_prime(67)
    67 is prime
    >>> is_prime(117)
    117 = 13 * 9
    >>> is_prime(16)
    16 = 4 * 4
    
    0 讨论(0)
  • 2020-11-21 06:02

    First, ordinary logic is helpful.

    If, for some reason, the terminating conditions can't be worked out, exceptions are a fall-back plan.

    class GetOutOfLoop( Exception ):
        pass
    
    try:
        done= False
        while not done:
            isok= False
            while not (done or isok):
                ok = get_input("Is this ok? (y/n)")
                if ok in ("y", "Y") or ok in ("n", "N") : 
                    done= True # probably better
                    raise GetOutOfLoop
            # other stuff
    except GetOutOfLoop:
        pass
    

    For this specific example, an exception may not be necessary.

    On other other hand, we often have "Y", "N" and "Q" options in character-mode applications. For the "Q" option, we want an immediate exit. That's more exceptional.

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

    My reason for coming here is that i had an outer loop and an inner loop like so:

    for x in array:
      for y in dont_use_these_values:
        if x.value==y:
          array.remove(x)  # fixed, was array.pop(x) in my original answer
          continue
    
      do some other stuff with x
    

    As you can see, it won't actually go to the next x, but will go to the next y instead.

    what i found to solve this simply was to run through the array twice instead:

    for x in array:
      for y in dont_use_these_values:
        if x.value==y:
          array.remove(x)  # fixed, was array.pop(x) in my original answer
          continue
    
    for x in array:
      do some other stuff with x
    

    I know this was a specific case of OP's question, but I am posting it in the hope that it will help someone think about their problem differently while keeping things simple.

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

    Try using an infinite generator.

    from itertools import repeat
    inputs = (get_input("Is this ok? (y/n)") for _ in repeat(None))
    response = (i.lower()=="y" for i in inputs if i.lower() in ("y", "n"))
    
    while True:
        #snip: print out current state
        if next(response):
            break
        #do more processing with menus and stuff
    
    0 讨论(0)
  • 2020-11-21 06:07

    PEP 3136 proposes labeled break/continue. Guido rejected it because "code so complicated to require this feature is very rare". The PEP does mention some workarounds, though (such as the exception technique), while Guido feels refactoring to use return will be simpler in most cases.

    0 讨论(0)
提交回复
热议问题