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

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

有办法解决这个问题吗?还是我必须先检查一次,跳出输入循环,然后再检查一次,如果用户满意,再跳出外部循环?


当前回答

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

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从句中。根据定义,如果没有内部断裂,就会发生这种情况。在这种情况下,继续巧妙地绕过外部中断。

其他回答

首先,普通的逻辑是有用的。

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

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"选项,我们要立即退出。这是比较特殊的。

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

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

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
while True:
    # Snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok.lower() == "y": 
            break_2 = True
        if ok.lower() == "n": 
            break
    if break_2:
        break

您可以定义一个变量(例如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

如果您只需要在复杂的for循环巢中测试边缘情况,则可以抛出1/0来引发异常。我保证不会告诉任何人。当您希望快速测试深度嵌套的for循环的单个迭代,并且不想跟踪大量break语句或注释掉大量代码时,这种方法非常方便。

是的,您可以将它包装在函数中并使用return,但在某些上下文中,这可能会非常麻烦。

入门级程序员的例子:

for i in first_iter:
    for j in second_iter:
        for k in third_iter:
            print(i_want_to_run_this_once_and_stop_executing(i,j,k))
            1/0
        code_that_takes_a_long_time()
    expensive_code()

在执行大量数据预处理的大型jupyter笔记本脚本中,这尤其方便。