打破嵌套循环

时间:2009-03-17 09:24:18

标签: python loops

  

可能重复:
  How to break out of multiple loops in Python?

是否有更简单的方法来突破嵌套循环而不是抛出异常? (在Perl中,您可以为每个循环指定标签,并至少继续外循环。)

for x in range(10):
    for y in range(10):
        print x*y
        if x*y > 50:
            "break both loops"

即,是否有比这更好的方式:

class BreakIt(Exception): pass

try:
    for x in range(10):
        for y in range(10):
            print x*y
            if x*y > 50:
                raise BreakIt
except BreakIt:
    pass

8 个答案:

答案 0 :(得分:611)

for x in xrange(10):
    for y in xrange(10):
        print x*y
        if x*y > 50:
            break
    else:
        continue  # only executed if the inner loop did NOT break
    break  # only executed if the inner loop DID break

同样适用于更深层循环:

for x in xrange(10):
    for y in xrange(10):
        for z in xrange(10):
            print x,y,z
            if x*y*z == 30:
                break
        else:
            continue
        break
    else:
        continue
    break

答案 1 :(得分:123)

至少有人建议,但也rejected。我不认为还有另一种方法,没有重复测试或重新组织代码。有时候有点烦人。

rejection message中,van Rossum先生提到使用return,这是非常明智的,我需要亲自记住。 :)

答案 2 :(得分:57)

如果您能够将循环代码提取到函数中,则可以使用return语句随时退出最外层循环。

def foo():
    for x in range(10):
        for y in range(10):
            print x*y
            if x*y > 50:
                return
foo()

如果很难提取该功能,你可以使用内部函数,如@ bjd2385所示,例如

def your_outer_func():
    ...
    def inner_func():
        for x in range(10):
            for y in range(10):
                print x*y
                if x*y > 50:
                    return
    inner_func()
    ...

答案 3 :(得分:38)

使用itertools.product!

from itertools import product
for x, y in product(range(10), range(10)):
    #do whatever you want
    break

这是python文档中itertools.product的链接: http://docs.python.org/library/itertools.html#itertools.product

你也可以用2个fors循环数组理解,并随时中断。

>>> [(x, y) for y in ['y1', 'y2'] for x in ['x1', 'x2']]
[
    ('x1', 'y1'), ('x2', 'y1'),
    ('x1', 'y2'), ('x2', 'y2')
]

(为清晰起见而格式化)

答案 4 :(得分:21)

有时我使用布尔变量。天真,如果你想,但我发现阅读非常灵活和舒适。测试变量可能会避免再次测试复杂的条件,也可能会收集内部循环中几个测试的结果。

    x_loop_must_break = False
    for x in range(10):
        for y in range(10):
            print x*y
            if x*y > 50:
                x_loop_must_break = True
                break
        if x_loop_must_break: break

答案 5 :(得分:16)

如果您要提出异常,可以提出StopIteration exception。这至少会使意图变得明显。

答案 6 :(得分:8)

您还可以重构代码以使用生成器。但这可能不适用于所有类型的嵌套循环。

答案 7 :(得分:3)

在这种特殊情况下,您可以使用itertools.product将循环与现代python(3.0,也可能是2.6)合并。

我自己认为这是一个经验法则,如果你嵌套了太多的循环(比如2个以上),你通常可以将其中一个循环提取到另一个方法中,或者将循环合并为一个循环,就像这种情况一样。