问题:如何摆脱多重循环?
给出以下代码(不起作用):
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
有没有办法使这项工作?还是我要进行一次检查以打破输入循环,然后再进行另一项限制较大的检查(如果用户满意的话)在外部循环中一起分解?
Given the following code (that doesn’t work):
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
Is there a way to make this work? Or do I have do one check to break out of the input loop, then another, more limited, check in the outside loop to break out all together if the user is satisfied?
回答 0
我的第一个直觉是将嵌套循环重构为一个函数,然后使用它return
来分解。
My first instinct would be to refactor the nested loop into a function and use return
to break out.
回答 1
这是另一种简短的方法。缺点是您只能打破外部循环,但是有时正是您想要的。
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子句中。根据定义,如果没有内部中断,则会发生这种情况。在这种情况下,可以continue
巧妙地规避外部中断。
Here’s another approach that is short. The disadvantage is that you can only break the outer loop, but sometimes it’s exactly what you want.
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
This uses the for / else construct explained at: Why does python use ‘else’ after for and while loops?
Key insight: It only seems as if the outer loop always breaks. But if the inner loop doesn’t break, the outer loop won’t either.
The continue
statement is the magic here. It’s in the for-else clause. By definition that happens if there’s no inner break. In that situation continue
neatly circumvents the outer break.
回答 2
PEP 3136建议标记为中断/继续。Guido 拒绝了它,因为“如此复杂的代码很少需要此功能”。PEP确实提到了一些解决方法(例如,异常技术),而Guido认为在大多数情况下,使用return进行重构将更为简单。
PEP 3136 proposes labeled break/continue. Guido rejected it because “code so complicated to require this feature is very rare”. The PEP does mention some workarounds, though (such as the exception technique), while Guido feels refactoring to use return will be simpler in most cases.
回答 3
首先,普通逻辑是有帮助的。
如果由于某种原因无法确定终止条件,则exceptions是后备计划。
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
对于此特定示例,可能不需要exceptions。
另一方面,在字符模式应用程序中,我们经常有“ Y”,“ N”和“ Q”选项。对于“ Q”选项,我们希望立即退出。那更exceptions。
First, ordinary logic is helpful.
If, for some reason, the terminating conditions can’t be worked out, exceptions are a fall-back plan.
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
For this specific example, an exception may not be necessary.
On other other hand, we often have “Y”, “N” and “Q” options in character-mode applications. For the “Q” option, we want an immediate exit. That’s more exceptional.
回答 4
我倾向于同意重构为函数通常是解决这种情况的最佳方法,但是对于确实需要打破嵌套循环的情况,这是@ S.Lott描述的异常引发方法的一个有趣变体。它使用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)Exception
每次使用都会获得一个定制的子类nested_break
;无需Exception
每次都声明自己的子类。
I tend to agree that refactoring into a function is usually the best approach for this sort of situation, but for when you really need to break out of nested loops, here’s an interesting variant of the exception-raising approach that @S.Lott described. It uses Python’s with
statement to make the exception raising look a bit nicer. Define a new context manager (you only have to do this once) with:
from contextlib import contextmanager
@contextmanager
def nested_break():
class NestedBreakException(Exception):
pass
try:
yield NestedBreakException
except NestedBreakException:
pass
Now you can use this context manager as follows:
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"
Advantages: (1) it’s slightly cleaner (no explicit try-except block), and (2) you get a custom-built Exception
subclass for each use of nested_break
; no need to declare your own Exception
subclass each time.
回答 5
首先,您还可以考虑使获取和验证输入的过程成为一个函数。在该函数中,您可以只返回正确的值,否则返回while循环。这从根本上消除了您解决的问题,通常可以在更一般的情况下使用(突破多个循环)。如果您绝对必须在您的代码中保留此结构,并且真的不想处理簿记布尔值…
您还可以按以下方式使用goto(从此处使用April Fools模块):
#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”以及所有其他功能,但是在像这样的奇怪情况下它可以很好地工作。
First, you may also consider making the process of getting and validating the input a function; within that function, you can just return the value if its correct, and keep spinning in the while loop if not. This essentially obviates the problem you solved, and can usually be applied in the more general case (breaking out of multiple loops). If you absolutely must keep this structure in your code, and really don’t want to deal with bookkeeping booleans…
You may also use goto in the following way (using an April Fools module from here):
#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
I know, I know, “thou shalt not use goto” and all that, but it works well in strange cases like this.
回答 6
引入一个新变量,将其用作“循环断路器”。首先给它分配一些东西(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 # <--- !
如果您有无限循环,这是唯一的出路。对于其他循环,执行速度实际上要快得多。如果您有许多嵌套循环,这也适用。您可以全部退出,也可以退出几个。无限可能!希望这对您有所帮助!
Introduce a new variable that you’ll use as a ‘loop breaker’. First assign something to it(False,0, etc.), and then, inside the outer loop, before you break from it, change the value to something else(True,1,…). Once the loop exits make the ‘parent’ loop check for that value. Let me demonstrate:
breaker = False #our mighty loop exiter!
while True:
while True:
if conditionMet:
#insert code here...
breaker = True
break
if breaker: # the interesting part!
break # <--- !
If you have an infinite loop, this is the only way out; for other loops execution is really a lot faster. This also works if you have many nested loops. You can exit all, or just a few. Endless possibilities! Hope this helped!
回答 7
要打破多个嵌套循环而不重构为函数,请使用带有内置StopIteration异常的“模拟goto语句” :
try:
for outer in range(100):
for inner in range(100):
if break_early():
raise StopIteration
except StopIteration: pass
见这个讨论关于使用goto语句的嵌套循环的突破。
To break out of multiple nested loops, without refactoring into a function, make use of a “simulated goto statement” with the built-in StopIteration exception:
try:
for outer in range(100):
for inner in range(100):
if break_early():
raise StopIteration
except StopIteration: pass
See this discussion on the use of goto statements for breaking out of nested loops.
回答 8
keeplooping=True
while keeplooping:
#Do Stuff
while keeplooping:
#do some other stuff
if finisheddoingstuff(): keeplooping=False
或类似的东西。您可以在内部循环中设置一个变量,并在内部循环退出后立即在外部循环中检查它,如果合适的话,可以中断。我有点像GOTO方法,但前提是您不介意使用愚人节的笑话模块-它不是Python语言的,但确实有道理。
keeplooping=True
while keeplooping:
#Do Stuff
while keeplooping:
#do some other stuff
if finisheddoingstuff(): keeplooping=False
or something like that. You could set a variable in the inner loop, and check it in the outer loop immediately after the inner loop exits, breaking if appropriate. I kinda like the GOTO method, provided you don’t mind using an April Fool’s joke module – its not Pythonic, but it does make sense.
回答 9
这不是最漂亮的方法,但是我认为这是最好的方法。
def loop():
while True:
#snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y": return
if ok == "n" or ok == "N": break
#do more processing with menus and stuff
我很确定您也可以在这里使用递归来解决问题,但是我不知道这是否对您来说是个好选择。
This isn’t the prettiest way to do it, but in my opinion, it’s the best way.
def loop():
while True:
#snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y": return
if ok == "n" or ok == "N": break
#do more processing with menus and stuff
I’m pretty sure you could work out something using recursion here as well, but I dunno if that’s a good option for you.
回答 10
如果两个条件都成立,为什么不继续循环呢?我认为这是一种更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
是不是
祝一切顺利。
And why not to keep looping if two conditions are true?
I think this is a more pythonic way:
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
Isn’t it?
All the best.
回答 11
将循环逻辑分解为一个迭代器,该迭代器产生循环变量并在完成后返回-这是一个简单的示例,它以行/列的形式排列图像,直到我们没有图像或放置位置为止:
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 ...
这具有拆分复杂的循环逻辑和处理的优点。
Factor your loop logic into an iterator that yields the loop variables and returns when done — here is a simple one that lays out images in rows/columns until we’re out of images or out of places to put them:
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 ...
This has the advantage of splitting up the complicated loop logic and the processing…
回答 12
在这种情况下,正如其他人指出的那样,功能分解也是解决之道。Python 3中的代码:
def user_confirms():
while True:
answer = input("Is this OK? (y/n) ").strip().lower()
if answer in "yn":
return answer == "y"
def main():
while True:
# do stuff
if user_confirms():
break
In this case, as pointed out by others as well, functional decomposition is the way to go. Code in Python 3:
def user_confirms():
while True:
answer = input("Is this OK? (y/n) ").strip().lower()
if answer in "yn":
return answer == "y"
def main():
while True:
# do stuff
if user_confirms():
break
回答 13
Python while ... else
结构中有一个隐藏的技巧,可用于模拟两次中断,而无需进行大量代码更改/添加。本质上,如果while
条件为假,else
则触发该块。既不exceptions,continue
也不break
触发该else
块。有关更多信息,请参见“ Python while语句上的Else子句 ”或while(v2.7)上的Python文档的答案。
while True:
#snip: print out current state
ok = ""
while ok != "y" and ok != "n":
ok = get_input("Is this ok? (y/n)")
if ok == "n" or ok == "N":
break # Breaks out of inner loop, skipping else
else:
break # Breaks out of outer loop
#do more processing with menus and stuff
唯一的缺点是您需要将双破折号条件移入while
条件(或添加一个标志变量)。for
循环也存在这种变化,else
在循环完成后将触发该块。
There is a hidden trick in the Python while ... else
structure which can be used to simulate the double break without much code changes/additions. In essence if the while
condition is false, the else
block is triggered. Neither exceptions, continue
or break
trigger the else
block. For more information see answers to “Else clause on Python while statement“, or Python doc on while (v2.7).
while True:
#snip: print out current state
ok = ""
while ok != "y" and ok != "n":
ok = get_input("Is this ok? (y/n)")
if ok == "n" or ok == "N":
break # Breaks out of inner loop, skipping else
else:
break # Breaks out of outer loop
#do more processing with menus and stuff
The only downside is that you need to move the double breaking condition into the while
condition (or add a flag variable). Variations of this exists also for the for
loop, where the else
block is triggered after loop completion.
回答 14
将迭代减少到单级循环的另一种方法是通过使用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`,但不幸的是,它已作为此副本的副本关闭了
Another way of reducing your iteration to a single-level loop would be via the use of generators as also specified in the python reference
for i, j in ((i, j) for i in A for j in B):
print(i , j)
if (some_condition):
break
You could scale it up to any number of levels for the loop
The downside is that you can no longer break only a single level. It’s all or nothing.
Another downside is that it doesn’t work with a while loop. I originally wanted to post this answer on Python – `break` out of all loops but unfortunately that’s closed as a duplicate of this one
回答 15
我来这里的原因是我有一个外部循环和一个内部循环,如下所示:
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的特定情况,但我希望将其发布,以帮助某人以不同的方式思考他们的问题,同时保持简单。
My reason for coming here is that i had an outer loop and an inner loop like so:
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
As you can see, it won’t actually go to the next x, but will go to the next y instead.
what i found to solve this simply was to run through the array twice instead:
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
I know this was a specific case of OP’s question, but I am posting it in the hope that it will help someone think about their problem differently while keeping things simple.
回答 16
尝试使用无限生成器。
from itertools import repeat
inputs = (get_input("Is this ok? (y/n)") for _ in repeat(None))
response = (i.lower()=="y" for i in inputs if i.lower() in ("y", "n"))
while True:
#snip: print out current state
if next(response):
break
#do more processing with menus and stuff
Try using an infinite generator.
from itertools import repeat
inputs = (get_input("Is this ok? (y/n)") for _ in repeat(None))
response = (i.lower()=="y" for i in inputs if i.lower() in ("y", "n"))
while True:
#snip: print out current state
if next(response):
break
#do more processing with menus and stuff
回答 17
通过使用一个函数:
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()
尝试通过注释掉来运行上面的代码return
。
不使用任何功能:
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
从底部开始注释掉包含一行的每一行来运行。
By using a function:
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()
Try running the above codes by commenting out the return
as well.
Without using any function:
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
Now, run the above codes as is first and then try running by commenting out each line containing break
one at a time from the bottom.
回答 18
将多个循环转换为单个可中断循环的一种简单方法是使用 numpy.ndindex
for i in range(n):
for j in range(n):
val = x[i, j]
break # still inside the outer loop!
for i, j in np.ndindex(n, n):
val = x[i, j]
break # you left the only loop there was!
您确实必须索引到您的对象中,而不是能够显式地遍历值,但是至少在简单的情况下,它似乎比大多数建议的答案简单约2至20倍。
An easy way to turn multiple loops into a single, breakable loop is to use numpy.ndindex
for i in range(n):
for j in range(n):
val = x[i, j]
break # still inside the outer loop!
for i, j in np.ndindex(n, n):
val = x[i, j]
break # you left the only loop there was!
You do have to index into your objects, as opposed to being able to iterate through the values explicitly, but at least in simple cases it seems to be approximately 2-20 times simpler than most of the answers suggested.
回答 19
# this version uses a level counter to choose how far to break out
break_levels = 0
while True:
# snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
break_levels = 1 # how far nested, excluding this break
break
if ok == "n" or ok == "N":
break # normal break
if break_levels:
break_levels -= 1
break # pop another level
if break_levels:
break_levels -= 1
break
# ...and so on
# this version uses a level counter to choose how far to break out
break_levels = 0
while True:
# snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
break_levels = 1 # how far nested, excluding this break
break
if ok == "n" or ok == "N":
break # normal break
if break_levels:
break_levels -= 1
break # pop another level
if break_levels:
break_levels -= 1
break
# ...and so on
回答 20
如果不喜欢将其重构为函数,可能会出现如下所示的小技巧
添加了1个break_level变量来控制while循环条件
break_level = 0
# while break_level < 3: # if we have another level of nested loop here
while break_level < 2:
#snip: print out current state
while break_level < 1:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y": break_level = 2 # break 2 level
if ok == "n" or ok == "N": break_level = 1 # break 1 level
probably little trick like below will do if not prefer to refactorial into function
added 1 break_level variable to control the while loop condition
break_level = 0
# while break_level < 3: # if we have another level of nested loop here
while break_level < 2:
#snip: print out current state
while break_level < 1:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y": break_level = 2 # break 2 level
if ok == "n" or ok == "N": break_level = 1 # break 1 level
回答 21
您可以定义一个变量(例如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
You can define a variable( for example break_statement ), then change it to a different value when two-break condition occurs and use it in if statement to break from second loop also.
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
回答 22
我想提醒您,Python中的函数可以在代码中间创建,并且可以透明地访问周围的变量以进行读取以及使用with nonlocal
或global
声明进行写入。
因此,您可以将函数用作“易碎控件结构”,从而定义要返回的位置:
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
I’d like to remind you that functions in Python can be created right in the middle of the code and can access the surrounding variables transparently for reading and with nonlocal
or global
declaration for writing.
So you can use a function as a “breakable control structure”, defining a place you want to return to:
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
回答 23
两种解决方案
举一个例子:这两个矩阵相等/相同吗?
matrix1和matrix2的大小相同,分别是n,2个二维矩阵。
第一个解决方案,没有一个功能
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
祝你今天愉快!
Solutions in 2 Ways
With an example: Are these two matrices equal/same?
matrix1 and matrix2 are same size, n, 2 dimentional matrices.
First Solution, without a function
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
Second Solution, with a function
This is the final solution for my case
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
Have a nice day!
回答 24
# this version breaks up to a certain label
break_label = None
while True:
# snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
break_label = "outer" # specify label to break to
break
if ok == "n" or ok == "N":
break
if break_label:
if break_label != "inner":
break # propagate up
break_label = None # we have arrived!
if break_label:
if break_label != "outer":
break # propagate up
break_label = None # we have arrived!
#do more processing with menus and stuff
# this version breaks up to a certain label
break_label = None
while True:
# snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
break_label = "outer" # specify label to break to
break
if ok == "n" or ok == "N":
break
if break_label:
if break_label != "inner":
break # propagate up
break_label = None # we have arrived!
if break_label:
if break_label != "outer":
break # propagate up
break_label = None # we have arrived!
#do more processing with menus and stuff
回答 25
希望这会有所帮助:
x = True
y = True
while x == True:
while y == True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
x,y = False,False #breaks from both loops
if ok == "n" or ok == "N":
break #breaks from just one
Hopefully this helps:
x = True
y = True
while x == True:
while y == True:
ok = get_input("Is this ok? (y/n)")
if ok == "y" or ok == "Y":
x,y = False,False #breaks from both loops
if ok == "n" or ok == "N":
break #breaks from just one
回答 26
这是一个似乎可行的实现:
break_ = False
for i in range(10):
if break_:
break
for j in range(10):
if j == 3:
break_ = True
break
else:
print(i, j)
唯一的缺点是您必须break_
在循环之前定义。
Here’s an implementation that seems to work:
break_ = False
for i in range(10):
if break_:
break
for j in range(10):
if j == 3:
break_ = True
break
else:
print(i, j)
The only draw back is that you have to define break_
before the loops.
回答 27
从语言层面上无法做到这一点。有些语言可以跳转,而其他语言则需要带参数,而python则不需要。
最好的选择是:
设置一个由外循环检查的标志,或设置外循环条件。
将循环放入函数中,然后使用return一次退出所有循环。
重新制定您的逻辑。
自1987年以来担任程序员的Vivek Nagarajan
使用功能
def doMywork(data):
for i in data:
for e in i:
return
使用标志
is_break = False
for i in data:
if is_break:
break # outer loop break
for e in i:
is_break = True
break # inner loop break
There is no way to do this from a language level. Some languages have
a goto others have a break that takes an argument, python does not.
The best options are:
Set a flag which is checked by the outer loop, or set the outer
loops condition.
Put the loop in a function and use return to break out of all the loops at once.
Reformulate your logic.
Credit goes to Vivek Nagarajan, Programmer since 1987
Using Function
def doMywork(data):
for i in data:
for e in i:
return
Using flag
is_break = False
for i in data:
if is_break:
break # outer loop break
for e in i:
is_break = True
break # inner loop break
回答 28
与之前的相似,但更紧凑。(布尔只是数字)
breaker = False #our mighty loop exiter!
while True:
while True:
ok = get_input("Is this ok? (y/n)")
breaker+= (ok.lower() == "y")
break
if breaker: # the interesting part!
break # <--- !
Similar like the one before, but more compact.
(Booleans are just numbers)
breaker = False #our mighty loop exiter!
while True:
while True:
ok = get_input("Is this ok? (y/n)")
breaker+= (ok.lower() == "y")
break
if breaker: # the interesting part!
break # <--- !
回答 29
由于此问题已成为进入特定循环的标准问题,因此我想用给出示例Exception
。
尽管在多重循环结构中没有名为“循环中断”的标签,但是我们可以利用用户定义的异常来进入我们选择的特定循环。考虑下面的示例,在该示例中,我们将在base-6编号系统中打印最多4位数字的所有数字:
class BreakLoop(Exception):
def __init__(self, counter):
Exception.__init__(self, 'Exception 1')
self.counter = counter
for counter1 in range(6): # Make it 1000
try:
thousand = counter1 * 1000
for counter2 in range(6): # Make it 100
try:
hundred = counter2 * 100
for counter3 in range(6): # Make it 10
try:
ten = counter3 * 10
for counter4 in range(6):
try:
unit = counter4
value = thousand + hundred + ten + unit
if unit == 4 :
raise BreakLoop(4) # Don't break from loop
if ten == 30:
raise BreakLoop(3) # Break into loop 3
if hundred == 500:
raise BreakLoop(2) # Break into loop 2
if thousand == 2000:
raise BreakLoop(1) # Break into loop 1
print('{:04d}'.format(value))
except BreakLoop as bl:
if bl.counter != 4:
raise bl
except BreakLoop as bl:
if bl.counter != 3:
raise bl
except BreakLoop as bl:
if bl.counter != 2:
raise bl
except BreakLoop as bl:
pass
当我们打印输出时,我们将永远不会得到单位位置为4的任何值。在那种情况下,我们不会像BreakLoop(4)
引发和陷入同一循环那样从任何循环中中断。同样,只要十位有3,我们就会使用进入第三循环BreakLoop(3)
。每当百位有5时,我们就使用进入第二个循环BreakLoop(2)
,每千位有2时,我们使用进入第一个循环BreakLoop(1)
。
简而言之,在内部循环中引发Exception(内置的或用户定义的),然后将其捕获到要从中恢复控制的循环中。如果要中断所有循环,请在所有循环之外捕获Exception。(我没有在示例中显示这种情况)。
Since this question has become a standard question for breaking into a particular loop, I would like to give my answer with example using Exception
.
Although there exists no label named breaking of loop in multipally looped construct, we can make use of User-defined Exceptions to break into a particular loop of our choice. Consider the following example where let us print all numbers upto 4 digits in base-6 numbering system:
class BreakLoop(Exception):
def __init__(self, counter):
Exception.__init__(self, 'Exception 1')
self.counter = counter
for counter1 in range(6): # Make it 1000
try:
thousand = counter1 * 1000
for counter2 in range(6): # Make it 100
try:
hundred = counter2 * 100
for counter3 in range(6): # Make it 10
try:
ten = counter3 * 10
for counter4 in range(6):
try:
unit = counter4
value = thousand + hundred + ten + unit
if unit == 4 :
raise BreakLoop(4) # Don't break from loop
if ten == 30:
raise BreakLoop(3) # Break into loop 3
if hundred == 500:
raise BreakLoop(2) # Break into loop 2
if thousand == 2000:
raise BreakLoop(1) # Break into loop 1
print('{:04d}'.format(value))
except BreakLoop as bl:
if bl.counter != 4:
raise bl
except BreakLoop as bl:
if bl.counter != 3:
raise bl
except BreakLoop as bl:
if bl.counter != 2:
raise bl
except BreakLoop as bl:
pass
When we print the output, we will never get any value whose unit place is with 4. In that case, we don’t break from any loop as BreakLoop(4)
is raised and caught in same loop. Similarly, whenever ten place is having 3, we break into third loop using BreakLoop(3)
. Whenever hundred place is having 5, we break into second loop using BreakLoop(2)
and whenver the thousand place is having 2, we break into first loop using BreakLoop(1)
.
In short, raise your Exception (in-built or user defined) in the inner loops, and catch it in the loop from where you want to resume your control to. If you want to break from all loops, catch the Exception outside all the loops. (I have not shown this case in example).