跳出嵌套循环

发布于 2024-07-15 02:56:19 字数 516 浏览 7 评论 0原文

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

Is there an easier way to break out of nested loops than throwing an exception? (In Perl, you can give labels to each loop and at least continue an outer loop.)

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

I.e., is there a nicer way than:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

像极了他 2024-07-22 02:56:19
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
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

The same works for deeper loops:

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
怼怹恏 2024-07-22 02:56:19

它至少被建议过,但也被拒绝。 我认为除了重复测试或重新组织代码之外,没有其他方法。 有时有点烦人。

拒绝消息中,van Rossum 先生提到使用 < code>return,这非常明智,也是我个人需要记住的。 :)

It has at least been suggested, but also rejected. I don't think there is another way, short of repeating the test or re-organizing the code. It is sometimes a bit annoying.

In the rejection message, Mr van Rossum mentions using return, which is really sensible and something I need to remember personally. :)

撧情箌佬 2024-07-22 02:56:19

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

If you're able to extract the loop code into a function, a return statement can be used to exit the outermost loop at any time.

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

If it's hard to extract that function you could use an inner function, as @bjd2385 suggests, e.g.

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()
    ...
昔日梦未散 2024-07-22 02:56:19

使用 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 个 for 的数组理解,并在需要时随时中断。

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

Use itertools.product!

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

Here's a link to itertools.product in the python documentation:
http://docs.python.org/library/itertools.html#itertools.product

You can also loop over an array comprehension with 2 fors in it, and break whenever you want to.

>>> [(x, y) for y in ['y1', 'y2'] for x in ['x1', 'x2']]
[
    ('x1', 'y1'), ('x2', 'y1'),
    ('x1', 'y2'), ('x2', 'y2')
]
一页 2024-07-22 02:56:19

有时我使用布尔变量。 天真,如果你愿意的话,但我发现它非常灵活且读起来很舒服。 测试变量可以避免再次测试复杂的条件,并且还可以收集内部循环中的多次测试的结果。

    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

Sometimes I use a boolean variable. Naive, if you want, but I find it quite flexible and comfortable to read. Testing a variable may avoid testing again complex conditions and may also collect results from several tests in inner loops.

    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
心的位置 2024-07-22 02:56:19

如果您要引发异常,则可以引发 StopIteration 异常。 这至少会让意图变得明显。

If you're going to raise an exception, you might raise a StopIteration exception. That will at least make the intent obvious.

維他命╮ 2024-07-22 02:56:19

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

You can also refactor your code to use a generator. But this may not be a solution for all types of nested loops.

偏爱你一生 2024-07-22 02:56:19

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

我自己认为这是一条经验法则,如果您嵌套太多循环(例如,超过 2 个),您通常可以将其中一个循环提取到另一种方法中,或者将循环合并为一个,如下所示案件。

In this particular case, you can merge the loops with a modern python (3.0 and probably 2.6, too) by using itertools.product.

I for myself took this as a rule of thumb, if you nest too many loops (as in, more than 2), you are usually able to extract one of the loops into a different method or merge the loops into one, as in this case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文