给定以下代码(不起作用):
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
我倾向于认为重构到函数中通常是这种情况的最佳方法,但是当您确实需要打破嵌套循环时,这里有一个有趣的异常引发方法的变体@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
另一种将迭代减少到单层循环的方法是使用生成器,这也在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”跳出所有循环,但不幸的是,它被关闭为这个循环的副本