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

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

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


当前回答

通过使用函数:

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

尝试通过注释掉返回值来运行上面的代码。

不使用任何函数:

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的每一行。

其他回答

要跳出多个嵌套循环,而不需要重构为函数,可以使用带有内置StopIteration异常的“模拟goto语句”:

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

except StopIteration: pass

请参阅使用goto语句打破嵌套循环的讨论。

我的第一反应是将嵌套循环重构为一个函数,并使用return来跳出。

以下是一个非常简短的版本: 创建名为break_out_nested.py的文件

import itertools
import sys

it = sys.modules[__name__] # this allows us to share variables with break_out_nested.py when we import it 


def bol(*args):
    condi = args[-1] # the condition function
    i = args[:-1] # all iterables 
    for p in itertools.product(*i): # itertools.product creates the nested loop
        if condi(): # if the condition is True, we return 
            return
        yield p # if not, we yield the result 

现在你只需要几行就可以打破嵌套的循环(数据来自Rafiq的例子)

from break_out_nested import it, bol # import what we have just created

# you need to create new variables as attributes of it,
# because break_out_nested has only access to these variables
it.i, it.j, it.k = 1, 1, 1
# the break condition
def cond(): return it.i % 3 == 0 and it.j % 3 == 0 and it.k % 3 == 0

# The condition will be checked in each loop 
for it.i, it.j, it.k in bol(range(1, 6, 1), range(1, 11, 2, ), range(1, 21, 4), cond):
    print(it.i, it.j, it.k)

更多的例子:

def cond(): return it.i + it.j + it.k == 777

it.i, it.j, it.k = 0, 0, 0
for it.i, it.j, it.k in bol(range(100), range(1000), range(10000), cond):
    print(it.i, it.j, it.k)




def cond(): return it.i + it.j + it.k >= 100000

it.i, it.j, it.k = 0, 0, 0
# you dont have to use it.i, it.j, it.k as the loop variables, you can
# use anything you want, but you have to update the variables somewhere
for i, j, k in bol(range(100), range(1000), range(10000), cond):
    it.i, it.j, it.k = i * 10, j * 100, k * 100
    print(it.i, it.j, it.k)

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

我认为这是一种更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

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

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

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