在Python中命名循环

29 投票
4 回答
35308 浏览
提问于 2025-04-17 07:54

我最近看到一个关于在Java中给循环命名的问题,里面提到了一种解决方案。

我在想,Python里有没有类似的循环命名系统。我遇到过好几次需要从内层的for循环跳出到外层for循环的情况。通常,我会把内层循环放在一个函数里,然后这个函数返回一个布尔值,用来作为跳出的条件。不过,如果能给循环命名来实现跳出,那看起来会简单很多,我想试试,如果Python里有这样的功能的话。

有没有人知道呢?

4 个回答

15

虽然在某些编程语言中有理由使用命名循环,但在Python中你可以很容易地避免这样做,而且不会影响代码的可读性。

下面是这个例子的Python实现:

>>> try:
    for i in xrange(0,5):
        for j in xrange(0,6):
            if i*j > 6:
                print "Breaking"
                raise StopIteration
            print i," ",j
except StopIteration:
    print "Done"


0   0
0   1
0   2
0   3
0   4
0   5
1   0
1   1
1   2
1   3
1   4
1   5
2   0
2   1
2   2
2   3
Breaking
Done
>>> 

我通过把内部循环放在一个函数里来解决这个问题,这个函数会返回一个布尔值(真或假),这个值可以用作跳出循环的条件。

我觉得你应该试试这个方法。这种做法非常符合Python的风格,简单又易读。

21

这里有一种方法可以通过上下文管理器来跳出多个嵌套的代码块:

import contextlib

@contextlib.contextmanager
def escapable():
    class Escape(RuntimeError): pass
    class Unblock(object):
        def escape(self):
            raise Escape()

    try:
        yield Unblock()
    except Escape:
        pass

你可以用它来跳出多个循环:

with escapable() as a:
    for i in xrange(30):
        for j in xrange(30):
            if i * j > 6:
                a.escape()

而且你甚至可以把它们嵌套在一起:

with escapable() as a:
    for i in xrange(30):
        with escapable() as b:
            for j in xrange(30):
                if i * j == 12:
                    b.escape()  # Break partway out
                if i * j == 40:
                    a.escape()  # Break all the way out
20

曾经有个提议想在Python中加入“命名循环”,这个提议叫做 PEP3136,不过最后被拒绝了,具体原因可以在 这里 找到。拒绝的主要原因是,这种写法在实际编程中能提高代码可读性的情况非常少。

撰写回答