给定以下代码(不起作用):
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
有办法解决这个问题吗?还是我必须先检查一次,跳出输入循环,然后再检查一次,如果用户满意,再跳出外部循环?
首先,您还可以考虑将获取和验证输入的过程作为一个函数;在该函数中,如果值正确,则返回值,如果不正确,则继续在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”之类的,但它在这种奇怪的情况下很管用。
将循环逻辑分解为迭代器,迭代器产生循环变量并在完成时返回——这里有一个简单的迭代器,它将图像按行/列排列,直到我们用完图像或找不到放置它们的位置:
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 ...
这样做的优点是将复杂的循环逻辑和处理分开。
我来这里的原因是我有一个外循环和一个内循环,像这样:
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问题的一个具体案例,但我发布它是希望它能帮助人们以不同的方式思考他们的问题,同时保持事情简单。
引入一个新变量作为“循环打破器”。首先给它赋值(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 # <--- !
如果你有一个无限循环,这是唯一的出路;对于其他循环,执行速度要快得多。如果你有很多嵌套循环,这也适用。你可以退出全部,也可以只退出一部分。无尽的可能性!希望这对你有所帮助!