在Python中命名循环

ins*_*get 15 python label for-loop break

我最近读到了这个问题,它有一个关于在Java中标记循环的解决方案.

我想知道Python中是否存在这样的循环命名系统.我曾多次遇到过需要for从内for循环中突破外循环的情况.通常,我通过将内部循环放在一个返回(以及其他)布尔值的函数中来解决这个问题,该布尔值用作断开条件.但是标记循环的中断似乎要简单得多,我想尝试一下,如果python中存在这样的功能

有谁知道它是否存在?

Stu*_*Gla 15

这是使用上下文管理器打破多个嵌套块的方法:

import contextlib

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

    try:
        yield Unblock()
    except Escape:
        pass
Run Code Online (Sandbox Code Playgroud)

您可以使用它来打破多个循环:

with escapable() as a:
    for i in xrange(30):
        for j in xrange(30):
            if i * j > 6:
                a.escape()
Run Code Online (Sandbox Code Playgroud)

你甚至可以嵌套它们:

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
Run Code Online (Sandbox Code Playgroud)

  • 是的,这比简单地执行循环更具可读性;`break 2` (php) 或 `Continue Loop1;` (javascript).. 另外,这个缩进地狱意大利面条代码真的有多 Pythonic 吗?使用“raise StopIteration”似乎是最干净、最易读、Pythonic 的解决方案 (4认同)

GWW*_*GWW 11

有一个建议在python PEP3136中包含命名循环,但是,它在这里被解释.拒绝主要是由于极少数情况下,通过包含此构造可以提高代码可读性.


Abh*_*jit 9

虽然有理由在语言构造中包含命名循环,但您可以轻松地在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
>>> 
Run Code Online (Sandbox Code Playgroud)

我通过将内部循环放在一个返回(以及其他)布尔值的函数中来解决这个问题,该布尔值用作断开条件.

我想你应该试试这个.这是非常pythonic,简单和可读.

  • +1.在Python中使用流控制的异常是完美的,尽管在其他语言中它被认为是不好的风格,通常是出于性能原因. (2认同)
  • 如果我只想"继续"外循环而不是停止它会怎么样? (2认同)
  • @Guillochon只需将 try 语句放入第一个 for 循环中 (2认同)