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

当前回答

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

其他回答

有时我使用布尔变量。如果你想说幼稚的话,但我觉得这本书读起来很灵活,很舒服。测试一个变量可以避免再次测试复杂的条件,还可以从内部循环中的几个测试中收集结果。

    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

如果能够将循环代码提取到函数中,则可以使用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()
    ...

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

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

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