如何跳出多重循环?

发布于 2024-07-06 15:20:22 字数 372 浏览 6 评论 0原文

给出以下代码(不起作用):

while True:
    # Snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok.lower() == "y": break 2 # This doesn't work :(
        if ok.lower() == "n": break

    # Do more processing with menus and stuff

有没有办法让它工作? 或者,如果用户满意,我是否必须进行一项检查以打破输入循环,然后进行另一项更有限的检查以在外部循环中一起打破?

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)")
        if ok.lower() == "y": break 2 # This doesn't work :(
        if ok.lower() == "n": break

    # Do more processing with menus and stuff

Is there a way to make this work? Or do I have do one check to break out of the input loop, then another, more limited, check in the outside loop to break out all together if the user is satisfied?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

醉殇 2024-07-13 15:20:22

我的第一直觉是将嵌套循环重构为函数并使用 return 来突破。

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

面如桃花 2024-07-13 15:20:22

这是另一种简短的方法。 缺点是你只能打破外层循环,但有时这正是你想要的。

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

这使用了 for / else 构造,解释如下: 为什么python 在 for 和 while 循环之后使用“else”?

关键见解:它只是看起来好像外部循环总是中断。 但是如果内部循环不中断,外部循环也不会中断。

continue 语句就是这里的魔力。 它位于 for-else 子句中。 根据定义,如果没有内部中断,就会发生这种情况。 在这种情况下,继续巧妙地绕过了外部中断。

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.

逆光飞翔i 2024-07-13 15:20:22

PEP 3136 建议标记为“中断/继续”。 Guido 拒绝了它,因为“代码太复杂了,需要这个功能非常罕见”。 不过,PEP 确实提到了一些解决方法(例如异常技术),而 Guido 认为在大多数情况下使用 return 进行重构会更简单。

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.

将军与妓 2024-07-13 15:20:22

首先,普通逻辑是有帮助的。

如果由于某种原因无法制定终止条件,则例外是一个后备计划。

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

对于这个具体示例,可能不需要例外。

另一方面,在字符模式应用程序中我们经常有“Y”、“N”和“Q”选项。 对于“Q”选项,我们希望立即退出。 那就更特别了。

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.

揪着可爱 2024-07-13 15:20:22

引入一个新变量,将其用作“循环断路器”。 首先为其分配一些内容(False、0 等),然后在外循环内部,在中断之前将值更改为其他内容(True、1、...)。 循环退出后,让“父”循环检查该值。 让我演示一下:

breaker = False #our mighty loop exiter!
while True:
    while True:
        if conditionMet:
            #insert code here...
            breaker = True 
            break
    if breaker: # the interesting part!
        break   # <--- !

如果你有一个无限循环,这是唯一的出路; 对于其他循环执行速度确实要快得多。 如果您有许多嵌套循环,这也适用。 您可以退出全部或仅退出一些。 无限可能! 希望这有帮助!

Introduce a new variable that you'll use as a 'loop breaker'. First assign something to it(False,0, etc.), and then, inside the outer loop, before you break from it, change the value to something else(True,1,...). Once the loop exits make the 'parent' loop check for that value. Let me demonstrate:

breaker = False #our mighty loop exiter!
while True:
    while True:
        if conditionMet:
            #insert code here...
            breaker = True 
            break
    if breaker: # the interesting part!
        break   # <--- !

If you have an infinite loop, this is the only way out; for other loops execution is really a lot faster. This also works if you have many nested loops. You can exit all, or just a few. Endless possibilities! Hope this helped!

Saygoodbye 2024-07-13 15:20:22

我倾向于认为,重构为函数通常是这种情况的最佳方法,但是当您确实需要打破嵌套循环时,这里有一个有趣的异常引发方法变体@S.Lott 描述的。 它使用 Python 的 with 语句来使异常引发看起来更好一些。 定义一个新的上下文管理器(您只需执行一次):

from contextlib import contextmanager

@contextmanager
def nested_break():
    class NestedBreakException(Exception):
        pass
    try:
        yield NestedBreakException
    except NestedBreakException:
        pass

现在您可以按如下方式使用此上下文管理器:

with nested_break() as mylabel:
    while True:
        print("current state")
        while True:
            ok = input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": raise mylabel
            if ok == "n" or ok == "N": break
        print("more processing")

优点:(1) 它稍微干净一些(没有显式的 try- except 块),并且 (2) 您会得到一个为每次使用nested_break定制Exception子类; 无需每次都声明自己的 Exception 子类。

I tend to agree that refactoring into a function is usually the best approach for this sort of situation, but for when you really need to break out of nested loops, here's an interesting variant of the exception-raising approach that @S.Lott described. It uses Python's with statement to make the exception raising look a bit nicer. Define a new context manager (you only have to do this once) with:

from contextlib import contextmanager

@contextmanager
def nested_break():
    class NestedBreakException(Exception):
        pass
    try:
        yield NestedBreakException
    except NestedBreakException:
        pass

Now you can use this context manager as follows:

with nested_break() as mylabel:
    while True:
        print("current state")
        while True:
            ok = input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": raise mylabel
            if ok == "n" or ok == "N": break
        print("more processing")

Advantages: (1) it's slightly cleaner (no explicit try-except block), and (2) you get a custom-built Exception subclass for each use of nested_break; no need to declare your own Exception subclass each time.

栀梦 2024-07-13 15:20:22

首先,您还可以考虑将获取和验证输入的过程设为函数; 在该函数中,如果值正确,您可以返回该值,如果不正确,则在 while 循环中继续旋转。 这基本上消除了您解决的问题,并且通常可以应用于更一般的情况(打破多个循环)。 如果您绝对必须在代码中保留此结构,并且确实不想处理簿记布尔值...

您还可以按以下方式使用 goto (使用 这里):

#import the stuff
from goto import goto, label

while True:
    #snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": goto .breakall
        if ok == "n" or ok == "N": break
    #do more processing with menus and stuff
label .breakall

我知道,我知道,“你不应该使用 goto”之类的,但它在奇怪的情况下效果很好像这样的情况。

First, you may also consider making the process of getting and validating the input a function; within that function, you can just return the value if its correct, and keep spinning in the while loop if not. This essentially obviates the problem you solved, and can usually be applied in the more general case (breaking out of multiple loops). If you absolutely must keep this structure in your code, and really don't want to deal with bookkeeping booleans...

You may also use goto in the following way (using an April Fools module from here):

#import the stuff
from goto import goto, label

while True:
    #snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": goto .breakall
        if ok == "n" or ok == "N": break
    #do more processing with menus and stuff
label .breakall

I know, I know, "thou shalt not use goto" and all that, but it works well in strange cases like this.

羁拥 2024-07-13 15:20:22

要打破多个嵌套循环,而不重构为函数,请使用带有内置 StopIteration 异常

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

except StopIteration: pass

请参阅 此讨论关于使用 goto 语句来打破嵌套循环。

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.

瑕疵 2024-07-13 15:20:22
keeplooping = True
while keeplooping:
    # Do stuff
    while keeplooping:
          # Do some other stuff
          if finisheddoingstuff():
              keeplooping = False

或类似的东西。

您可以在内部循环中设置一个变量,并在内部循环退出后立即在外部循环中检查它,如果合适则中断。 我有点喜欢 GOTO 方法,前提是你不介意使用愚人节笑话模块 - 它不是 Pythonic,但它确实有意义。

keeplooping = True
while keeplooping:
    # Do stuff
    while keeplooping:
          # Do some other stuff
          if finisheddoingstuff():
              keeplooping = False

or something like that.

You could set a variable in the inner loop, and check it in the outer loop immediately after the inner loop exits, breaking if appropriate. I kind of like the GOTO method, provided you don't mind using an April Fool's joke module - it’s not Pythonic, but it does make sense.

探春 2024-07-13 15:20:22

这不是最漂亮的方法,但在我看来,这是最好的方法。

def loop():
    while True:
    #snip: print out current state
        while True:
            ok = get_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": return
            if ok == "n" or ok == "N": break
        #do more processing with menus and stuff

我很确定您也可以在这里使用递归来解决一些问题,但我不知道这对您来说是否是一个不错的选择。

This isn't the prettiest way to do it, but in my opinion, it's the best way.

def loop():
    while True:
    #snip: print out current state
        while True:
            ok = get_input("Is this ok? (y/n)")
            if ok == "y" or ok == "Y": return
            if ok == "n" or ok == "N": break
        #do more processing with menus and stuff

I'm pretty sure you could work out something using recursion here as well, but I don't know if that's a good option for you.

长亭外,古道边 2024-07-13 15:20:22

如果两个条件都为真,则继续循环。

我认为这是一种更Pythonic的方式:

dejaVu = True

while dejaVu:
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y" or ok == "n" or ok == "N":
            dejaVu = False
            break

Keep looping if two conditions are true.

I think this is a more Pythonic way:

dejaVu = True

while dejaVu:
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y" or ok == "n" or ok == "N":
            dejaVu = False
            break
也只是曾经 2024-07-13 15:20:22

没有办法从语言层面做到这一点。 有些语言有
goto 其他有一个需要参数的中断,而 python 没有。

最好的选择是:

  1. 设置一个由外循环检查的标志,或者设置外循环
    循环条件。

  2. 将循环放入函数中,然后使用 return 一次性跳出所有循环。

  3. 重新表述你的逻辑。

信用


使用函数

def doMywork(data):
    for i in data:
       for e in i:
         return 

使用标志

is_break = False
for i in data:
   if is_break:
      break # outer loop break
   for e in i:
      is_break = True
      break # inner loop break

There is no way to do this from a language level. Some languages have
a goto others have a break that takes an argument, python does not.

The best options are:

  1. Set a flag which is checked by the outer loop, or set the outer
    loops condition.

  2. Put the loop in a function and use return to break out of all the loops at once.

  3. Reformulate your logic.

Credit


Using Function

def doMywork(data):
    for i in data:
       for e in i:
         return 

Using flag

is_break = False
for i in data:
   if is_break:
      break # outer loop break
   for e in i:
      is_break = True
      break # inner loop break
旧伤还要旧人安 2024-07-13 15:20:22

将循环逻辑分解为一个迭代器,该迭代器生成循环变量并在完成后返回 - 这是一个简单的迭代器,它将图像布置在行/列中,直到我们没有图像或没有地方放置它们:

def it(rows, cols, images):
    i = 0
    for r in xrange(rows):
        for c in xrange(cols):
            if i >= len(images):
                return
            yield r, c, images[i]
            i += 1 

for r, c, image in it(rows=4, cols=4, images=['a.jpg', 'b.jpg', 'c.jpg']):
    ... do something with r, c, image ...

这有一个优点分解复杂的循环逻辑和处理......

Factor your loop logic into an iterator that yields the loop variables and returns when done -- here is a simple one that lays out images in rows/columns until we're out of images or out of places to put them:

def it(rows, cols, images):
    i = 0
    for r in xrange(rows):
        for c in xrange(cols):
            if i >= len(images):
                return
            yield r, c, images[i]
            i += 1 

for r, c, image in it(rows=4, cols=4, images=['a.jpg', 'b.jpg', 'c.jpg']):
    ... do something with r, c, image ...

This has the advantage of splitting up the complicated loop logic and the processing...

若水般的淡然安静女子 2024-07-13 15:20:22

将多个循环转变为单个可破坏循环的一种简单方法是使用 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!

您必须对对象进行索引,而不是能够显式地迭代值,但至少在简单的情况下,它似乎比大多数建议的答案简单 2-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.

忆离笙 2024-07-13 15:20:22

Python while ... else 结构中有一个隐藏的技巧,可以用来模拟双中断,而无需进行太多代码更改/添加。 本质上,如果 while 条件为 false,就会触发 else 块。 continuebreak 异常均不会触发 else 块。 有关详细信息,请参阅“Python while 语句的 Else 子句”的答案,或 Python 文档 while (v2.7)

while True:
    #snip: print out current state
    ok = ""
    while ok != "y" and ok != "n":
        ok = get_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N":
            break    # Breaks out of inner loop, skipping else

    else:
        break        # Breaks out of outer loop

    #do more processing with menus and stuff

唯一的缺点是您需要将双重中断条件移至 while 条件(或添加标志变量)。 for 循环也存在这种情况的变体,其中 else 块在循环完成后触发。

There is a hidden trick in the Python while ... else structure which can be used to simulate the double break without much code changes/additions. In essence if the while condition is false, the else block is triggered. Neither exceptions, continue or break trigger the else block. For more information see answers to "Else clause on Python while statement", or Python doc on while (v2.7).

while True:
    #snip: print out current state
    ok = ""
    while ok != "y" and ok != "n":
        ok = get_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N":
            break    # Breaks out of inner loop, skipping else

    else:
        break        # Breaks out of outer loop

    #do more processing with menus and stuff

The only downside is that you need to move the double breaking condition into the while condition (or add a flag variable). Variations of this exists also for the for loop, where the else block is triggered after loop completion.

甜味拾荒者 2024-07-13 15:20:22

在这种情况下,正如其他人所指出的那样,功能分解是正确的选择。 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

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
溺深海 2024-07-13 15:20:22

通过使用函数:

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()

尝试通过注释掉return来运行上述代码。

不使用任何函数:

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

现在,首先按原样运行上述代码,然后通过从底部开始一次注释掉包含 break 的每一行来尝试运行。

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.

温柔少女心 2024-07-13 15:20:22

将迭代减少为单级循环的另一种方法是使用生成器,如 python 参考

for i, j in ((i, j) for i in A for j in B):
    print(i , j)
    if (some_condition):
        break

您可以将其扩展到任意数量的循环级别。

缺点是您不能再只中断单个级别。 要么全有,要么全无。

另一个缺点是它不能与 while 循环一起使用。 我最初想在 Python - `break` 脱离所有循环 但不幸的是,它作为这个的重复而被关闭

Another way of reducing your iteration to a single-level loop would be via the use of generators as also specified in the python reference

for i, j in ((i, j) for i in A for j in B):
    print(i , j)
    if (some_condition):
        break

You could scale it up to any number of levels for the loop

The downside is that you can no longer break only a single level. It's all or nothing.

Another downside is that it doesn't work with a while loop. I originally wanted to post this answer on Python - `break` out of all loops but unfortunately that's closed as a duplicate of this one

花桑 2024-07-13 15:20:22

我想提醒您,Python 中的函数可以在代码中间创建,并且可以透明地访问周围的变量以供读取,并且可以使用 nonlocalglobal 声明用于写作。

因此,您可以使用函数作为“可破坏的控制结构”,定义您想要返回的位置:

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

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
℉服软 2024-07-13 15:20:22

尝试使用无限发生器。

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

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
演多会厌 2024-07-13 15:20:22
# 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
# 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
久隐师 2024-07-13 15:20:22
# this version breaks up to a certain label

break_label = None
while True:
    # snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y":
            break_label = "outer"   # specify label to break to
            break
        if ok == "n" or ok == "N":
            break
    if break_label:
        if break_label != "inner":
            break                   # propagate up
        break_label = None          # we have arrived!
if break_label:
    if break_label != "outer":
        break                       # propagate up
    break_label = None              # we have arrived!

#do more processing with menus and stuff
# this version breaks up to a certain label

break_label = None
while True:
    # snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y":
            break_label = "outer"   # specify label to break to
            break
        if ok == "n" or ok == "N":
            break
    if break_label:
        if break_label != "inner":
            break                   # propagate up
        break_label = None          # we have arrived!
if break_label:
    if break_label != "outer":
        break                       # propagate up
    break_label = None              # we have arrived!

#do more processing with menus and stuff
赏烟花じ飞满天 2024-07-13 15:20:22

这是一个似乎有效的实现:

break_ = False
for i in range(10):
    if break_:
        break
    for j in range(10):
        if j == 3:
            break_ = True
            break
        else:
            print(i, j)

唯一的缺点是您必须在循环之前定义 break_

Here's an implementation that seems to work:

break_ = False
for i in range(10):
    if break_:
        break
    for j in range(10):
        if j == 3:
            break_ = True
            break
        else:
            print(i, j)

The only draw back is that you have to define break_ before the loops.

池予 2024-07-13 15:20:22

我个人会做的是使用一个布尔值,当我准备好打破外循环时进行切换。 例如

while True:
    #snip: print out current state
    quit = False
    while True:
        ok = input("Is this ok? (y/n)")
        if ok.lower() == "y":
            quit = True
            break # this should work now :-)
        if ok.lower() == "n":
            quit = True
            break # This should work too :-)
    if quit:
        break
    #do more processing with menus and stuff

What I would personally do is use a boolean that toggles when I am ready to break out the outer loop. For example

while True:
    #snip: print out current state
    quit = False
    while True:
        ok = input("Is this ok? (y/n)")
        if ok.lower() == "y":
            quit = True
            break # this should work now :-)
        if ok.lower() == "n":
            quit = True
            break # This should work too :-)
    if quit:
        break
    #do more processing with menus and stuff
眼眸里的那抹悲凉 2024-07-13 15:20:22

两种解决方案

举个例子:这两个矩阵相等/相同吗?
矩阵 1 和矩阵 2 是相同大小的 n 二维矩阵。

第一个解决方案没有函数

same_matrices = True
inner_loop_broken_once = False
n = len(matrix1)

for i in range(n):
    for j in range(n):

        if matrix1[i][j] != matrix2[i][j]:
            same_matrices = False
            inner_loop_broken_once = True
            break

    if inner_loop_broken_once:
        break

第二个解决方案有函数

这是我的案例的最终解决方案。

def are_two_matrices_the_same (matrix1, matrix2):
    n = len(matrix1)
    for i in range(n):
        for j in range(n):
            if matrix1[i][j] != matrix2[i][j]:
                return False
    return True

Solutions in two ways

With an example: Are these two matrices equal/same?
matrix1 and matrix2 are the same size, n, two-dimensional matrices.

First solution, without a function

same_matrices = True
inner_loop_broken_once = False
n = len(matrix1)

for i in range(n):
    for j in range(n):

        if matrix1[i][j] != matrix2[i][j]:
            same_matrices = False
            inner_loop_broken_once = True
            break

    if inner_loop_broken_once:
        break

Second solution, with a function

This is the final solution for my case.

def are_two_matrices_the_same (matrix1, matrix2):
    n = len(matrix1)
    for i in range(n):
        for j in range(n):
            if matrix1[i][j] != matrix2[i][j]:
                return False
    return True
不寐倦长更 2024-07-13 15:20:22

如果不喜欢重构到函数中

添加 1 个break_level 变量来控制 while 循环条件,可能像下面这样的小技巧会起作用

break_level = 0
# while break_level < 3: # if we have another level of nested loop here
while break_level < 2:
    #snip: print out current state
    while break_level < 1:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": break_level = 2 # break 2 level
        if ok == "n" or ok == "N": break_level = 1 # break 1 level

probably little trick like below will do if not prefer to refactorial into function

added 1 break_level variable to control the while loop condition

break_level = 0
# while break_level < 3: # if we have another level of nested loop here
while break_level < 2:
    #snip: print out current state
    while break_level < 1:
        ok = get_input("Is this ok? (y/n)")
        if ok == "y" or ok == "Y": break_level = 2 # break 2 level
        if ok == "n" or ok == "N": break_level = 1 # break 1 level
洒一地阳光 2024-07-13 15:20:22

您可以定义一个变量(例如 break_statement ),然后在发生两次中断条件时将其更改为不同的值,并在 if 语句中使用它来从第二个循环中中断。

while True:
    break_statement=0
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N": 
            break
        if ok == "y" or ok == "Y": 
            break_statement=1
            break
    if break_statement==1:
        break

You can define a variable( for example break_statement ), then change it to a different value when two-break condition occurs and use it in if statement to break from second loop also.

while True:
    break_statement=0
    while True:
        ok = raw_input("Is this ok? (y/n)")
        if ok == "n" or ok == "N": 
            break
        if ok == "y" or ok == "Y": 
            break_statement=1
            break
    if break_statement==1:
        break
删除会话 2024-07-13 15:20:22

我来这里的原因是我有一个外循环和一个内循环,如下所示:

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

如您所见,它实际上不会转到下一个 x,而是会转到下一个 y。

我发现解决这个问题的方法就是运行两次数组:

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

我知道这是OP问题的一个具体情况,但我发布它是希望它能帮助人们以不同的方式思考他们的问题,同时保持事情简单。

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.

梦罢 2024-07-13 15:20:22

希望这有帮助:

x = True
y = True
while x == True:
    while y == True:
         ok = get_input("Is this ok? (y/n)") 
         if ok == "y" or ok == "Y":
             x,y = False,False #breaks from both loops
         if ok == "n" or ok == "N": 
             break #breaks from just one

Hopefully this helps:

x = True
y = True
while x == True:
    while y == True:
         ok = get_input("Is this ok? (y/n)") 
         if ok == "y" or ok == "Y":
             x,y = False,False #breaks from both loops
         if ok == "n" or ok == "N": 
             break #breaks from just one
潦草背影 2024-07-13 15:20:22

我最近遇到了这个问题,想要避免重复的 return 语句,这会隐藏逻辑错误,所以查看了 @yak 的想法。 这在嵌套 for 循环中效果很好,但不是很优雅。 另一种方法是在下一个循环之前检查条件:

b = None
for a in range(10):
    if something(a, b): # should never = True if b is None
        break
    for b in range(20):
        pass

这可能不适用于所有地方,但具有适应性,并且如果需要,具有允许重复条件而不是潜在结果的优点。

I came across this recently and, wanting to avoid a duplicate return statement, which can conceal logical errors, looked at @yak's idea. This works well within nested for loops but is not very elegant. An alternative is to check for the condition before the next loop:

b = None
for a in range(10):
    if something(a, b): # should never = True if b is None
        break
    for b in range(20):
        pass

This might not work everywhere but is adaptable and, if required, has the advantage of allowing the condition to be duplicated rather than a potential result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文