Python:继续在外循环中进行下一次迭代

Sah*_*has 114 python loops

我想知道是否有任何内置方法可以继续在python中的外循环中进行下一次迭代.例如,考虑代码:

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            continue
    ...block1...
Run Code Online (Sandbox Code Playgroud)

我希望这个continue语句退出jj循环并转到ii循环中的下一个项目.我可以通过其他方式实现这个逻辑(通过设置一个标志变量),但有一种简单的方法可以做到这一点,还是这就像要求太多?

cul*_*rón 132

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            break
    else:
        ...block1...
Run Code Online (Sandbox Code Playgroud)

Break 将打破内部循环,并且不会执行block1(仅当内​​循环正常退出时才会运行).

  • `for...else` 通常是一个有用的结构,尽管它可能会令人困惑。请记住,在这种情况下,`else` 的意思是“不中断”。 (4认同)
  • 对我来说,这听起来像是你正试图用for循环来做一些最好以不同方式接近的东西...... (3认同)

use*_*610 53

for i in ...:
    for j in ...:
        for k in ...:
            if something:
                # continue loop i
Run Code Online (Sandbox Code Playgroud)

在一般情况下,当您有多个循环级别并且break不适合您时(因为您想继续其中一个上部循环,而不是当前循环之上的循环),您可以执行以下操作之一

将要转义的循环重构为函数

def inner():
    for j in ...:
        for k in ...:
            if something:
                return


for i in ...:
    inner()
Run Code Online (Sandbox Code Playgroud)

缺点是您可能需要将一些变量传递给该新函数,这些变量以前在范围内.您可以将它们作为参数传递,在对象上创建实例变量(仅为此函数创建一个新对象,如果有意义),或全局变量,单例,等等(ehm,ehm).

或者你可以定义inner为嵌套函数,让它只捕获它需要的东西(可能会更慢?)

for i in ...:
    def inner():
        for j in ...:
            for k in ...:
                if something:
                    return
    inner()
Run Code Online (Sandbox Code Playgroud)

使用例外

从哲学上讲,这就是例外情况,在必要时通过结构化编程构建块(if,for,while)打破程序流.

优点是您不必将单个代码分成多个部分.如果它是在用Python编写时正在设计的某种计算,那么这很好.在这个早期阶段引入抽象可能会减慢你的速度.

这种方法的坏处是,解释器/编译器作者通常认为异常是例外的,并相应地对它们进行优化.

class ContinueI(Exception):
    pass


continue_i = ContinueI()

for i in ...:
    try:
        for j in ...:
            for k in ...:
                if something:
                    raise continue_i
    except ContinueI:
        continue
Run Code Online (Sandbox Code Playgroud)

为此创建一个特殊的异常类,这样您就不会冒险意外地消除其他异常.

还有别的东西

我相信还有其他解决方案.

  • 对我来说,使用 Exceptions 是实现这一目标的好方法。我同意@ user7610 - “从哲学上讲,这就是例外”。 (4认同)

Dav*_*ebb 40

在其他语言中,您可以标记循环并从标记循环中断. Python Enhancement Proposal(PEP)3136建议将这些添加到Python中,Guido拒绝了它:

但是,我拒绝它,因为代码如此复杂,需要这个功能是非常罕见的.在大多数情况下,现有的解决方法可以生成干净的代码,例如使用"return".虽然我确信有一些(罕见的)实际情况,代码的清晰度会受到重构的影响,这使得使用return成为可能,但这有两个问题所抵消:

  1. 复杂性永久地增加了语言.这不仅影响所有Python实现,还影响每个源分析工具,当然还有该语言的所有文档.

  2. 我期望该功能将被滥用而不会被正确使用,从而导致代码清晰度的净减少(在此后编写的所有Python代码中进行测量).懒惰的程序员无处不在,在你知道它之前,你手上有难以理解的代码.

所以,如果这是你希望你运气不好的话,那么看看其他答案之一,因为那里有很好的选择.

  • 这让我很难过。我不敢相信我同时爱又恨Python。如此美丽,却如此。 (5认同)
  • 所有冰雹 Guido 我们的 BDFL (4认同)
  • 这更像是一个红色的,而不是一个好的反驳,但在我看来,"for-else"的行为更复杂,更难以阅读,并且可能更容易被滥用(如果不是彻头彻尾的错误).命名循环将是.我想我会使用一个不同于'else`的关键字 - 或许像`resume`这样的关键字会不错?你在循环中"断开","简历"就在它之后? (4认同)
  • @jlh对我来说主要是wtf。有时我认为它不是出于合法目的而是为了与众不同而希望有所不同。这是一个很好的例子。我经常遇到打破外部循环的需要。 (4认同)
  • 有趣.我同意Guido的观点.虽然在某些情况下会很好,但它会被滥用.不实现它的另一个原因是,现在在C和Python之间来回移植代码非常简单.一旦Python开始学习其他语言缺乏的功能,这就变得更难了.例如,您可以在Python中的for循环上使用else语句...这使得代码对其他语言的可移植性降低. (3认同)

asm*_*rer 12

我想你可以这样做:

for ii in range(200):
    restart = False
    for jj in range(200, 400):
        ...block0...
        if something:
            restart = True
            break
    if restart:
        continue
    ...block1...
Run Code Online (Sandbox Code Playgroud)

  • 如果你之前从未见过`for`,'else`,那么接受的答案就不会更清楚了(我认为即使是大多数人也记不住他们的头脑如何运作). (9认同)
  • -1:OP明确表示他们知道他们可以做这样的事情,而这看起来就像是接受答案的杂乱版本(比你早8个月,所以你不能错过接受的答案)回答). (4认同)

Est*_*her 6

我们想要找到一些东西,然后停止内部迭代。我使用标志系统。

for l in f:
    flag = True
    for e in r:
        if flag==False:continue
        if somecondition:
            do_something()
            flag=False
Run Code Online (Sandbox Code Playgroud)

  • 也许是因为这里已经发布了基本上完全相同的内容,我猜......而“False:继续”的东西是......不寻常的格式。正如在“自然”系统中以指数为常态的情况一样,你只需要幸运几次就能积累大量的声誉点。无论如何,我的“最佳”答案通常是最不受欢迎的答案。 (2认同)

Khe*_*huk 6

我认为实现这一点的最简单方法之一是将“继续”替换为“中断”语句,即

for ii in range(200):
 for jj in range(200, 400):
    ...block0...
    if something:
        break
 ...block1...       
Run Code Online (Sandbox Code Playgroud)

例如,下面是简单的代码,可以查看它到底是如何进行的:

for i in range(10):
    print("doing outer loop")
    print("i=",i)
    for p in range(10):
        print("doing inner loop")
        print("p=",p)
        if p==3:
            print("breaking from inner loop")
            break
    print("doing some code in outer loop")
Run Code Online (Sandbox Code Playgroud)