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

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

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


当前回答

解决方法有两种

举个例子:这两个矩阵相等/相同吗? 矩阵x1和矩阵x2是相同大小的,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

其他回答

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

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

我倾向于认为重构到函数中通常是这种情况的最佳方法,但是当您确实需要打破嵌套循环时,这里有一个有趣的异常引发方法的变体@S。洛特。它使用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 = raw_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子类。

我想提醒你,Python中的函数可以在代码中间创建,并且可以透明地访问周围的变量以进行读取,也可以通过非局部或全局声明进行写入。

所以你可以使用一个函数作为“易碎的控制结构”,定义一个你想要返回的地方:

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

另一种将迭代减少到单层循环的方法是使用生成器,这也在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”跳出所有循环,但不幸的是,它被关闭为这个循环的副本