有没有比抛出异常更简单的方法来打破嵌套循环?(在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

当前回答

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

其他回答

至少有人提出过,但也有人拒绝。除了重复测试或重新组织代码之外,我不认为还有其他方法。这有时有点烦人。

在拒绝信中,范·罗森先生提到了使用return,这是非常明智的,也是我个人需要记住的。:)

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

对于我自己来说,这是一个经验法则,如果你嵌套了太多的循环(比如,超过2个),你通常能够将其中一个循环提取到一个不同的方法中,或者将循环合并为一个,就像在这种情况下。

您还可以重构代码以使用生成器。但这可能不是所有类型的嵌套循环的解决方案。

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

如果你要引发一个异常,你可能会引发一个StopIteration异常。这至少会让意图变得明显。