简体   繁体   English

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

[英]Python: Continuing to next iteration in outer loop

I wanted to know if there are any built-in ways to continue to next iteration in outer loop in python.我想知道是否有任何内置方法可以在 python 的外循环中继续下一次迭代。 For example, consider the code:例如,考虑以下代码:

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            continue
    ...block1...

I want this continue statement to exit the jj loop and goto next item in the ii loop.我希望这个 continue 语句退出 jj 循环并转到 ii 循环中的下一项。 I can implement this logic in some other way (by setting a flag variable), but is there an easy way to do this, or is this like asking for too much?我可以用其他方式实现这个逻辑(通过设置一个标志变量),但是有没有一种简单的方法来做到这一点,或者这是否要求太多?

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            break
    else:
        ...block1...

Break will break the inner loop, and block1 won't be executed (it will run only if the inner loop is exited normally). Break会中断内循环,block1 不会被执行(只有内循环正常退出才会运行)。

for i in ...:
    for j in ...:
        for k in ...:
            if something:
                # continue loop i

In a general case, when you have multiple levels of looping and break does not work for you (because you want to continue one of the upper loops, not the one right above the current one), you can do one of the following在一般情况下,当您有多个循环级别并且break对您不起作用(因为您想继续上层循环之一,而不是当前循环正上方的循环),您可以执行以下操作之一

Refactor the loops you want to escape from into a function将您想要转义的循环重构为一个函数

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


for i in ...:
    inner()

The disadvantage is that you may need to pass to that new function some variables, which were previously in scope.缺点是您可能需要向该新函数传递一些以前在作用域中的变量。 You can either just pass them as parameters, make them instance variables on an object (create a new object just for this function, if it makes sense), or global variables, singletons, whatever (ehm, ehm).您可以将它们作为参数传递,使它们成为对象上的实例变量(为这个函数创建一个新对象,如果有意义的话),或者全局变量,单例,等等(ehm,ehm)。

Or you can define inner as a nested function and let it just capture what it needs (may be slower?)或者你可以将inner定义为一个嵌套函数,让它只捕获它需要的东西(可能会更慢?)

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

Use exceptions使用异常

Philosophically, this is what exceptions are for, breaking the program flow through the structured programming building blocks (if, for, while) when necessary.从哲学上讲,这就是异常的用途,在必要时通过结构化编程构建块(if、for、while)打破程序流。

The advantage is that you don't have to break the single piece of code into multiple parts.优点是您不必将一段代码分成多个部分。 This is good if it is some kind of computation that you are designing while writing it in Python.如果它是您在用 Python 编写时正在设计的某种计算,这很好。 Introducing abstractions at this early point may slow you down.在这个早期引入抽象可能会减慢你的速度。

Bad thing with this approach is that interpreter/compiler authors usually assume that exceptions are exceptional and optimize for them accordingly.这种方法的坏处是解释器/编译器作者通常假设异常是异常的并相应地对其进行优化。

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

Create a special exception class for this, so that you don't risk accidentally silencing some other exception.为此创建一个特殊的异常类,这样您就不会冒意外使其他异常静音的风险。

Something else entirely完全不同的东西

I am sure there are still other solutions.我相信还有其他解决方案。

In other languages you can label the loop and break from the labelled loop.在其他语言中,您可以标记循环并中断标记的循环。 Python Enhancement Proposal (PEP) 3136 suggested adding these to Python but Guido rejected it : Python 增强提案 (PEP) 3136 建议将这些添加到 Python 中,Guido 拒绝了它

However, I'm rejecting it on the basis that code so complicated to require this feature is very rare.但是,我拒绝它的基础是代码如此复杂以至于需要此功能的情况非常罕见。 In most cases there are existing work-arounds that produce clean code, for example using 'return'.在大多数情况下,现有的变通方法可以生成干净的代码,例如使用“return”。 While I'm sure there are some (rare) real cases where clarity of the code would suffer from a refactoring that makes it possible to use return, this is offset by two issues:虽然我确信在某些(罕见的)真实情况下,代码的清晰度会受到重构的影响,从而可以使用 return,但这被两个问题所抵消:

  1. The complexity added to the language, permanently.永久性地增加了语言的复杂性。 This affects not only all Python implementations, but also every source analysis tool, plus of course all documentation for the language.这不仅会影响所有 Python 实现,还会影响每个源代码分析工具,当然还有该语言的所有文档。

  2. My expectation that the feature will be abused more than it will be used right, leading to a net decrease in code clarity (measured across all Python code written henceforth).我预计该功能将被滥用而不是正确使用,从而导致代码清晰度的净下降(在此后编写的所有 Python 代码中进行测量)。 Lazy programmers are everywhere, and before you know it you have an incredible mess on your hands of unintelligible code.懒惰的程序员无处不在,在不知不觉中,你手上的难懂代码已经一团糟。

So if that's what you were hoping for you're out of luck, but look at one of the other answers as there are good options there.因此,如果这就是您所希望的,那么您就不走运了,但请查看其他答案之一,因为那里有不错的选择。

I think you could do something like this:我认为你可以做这样的事情:

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

I think one of the easiest ways to achieve this is to replace "continue" with "break" statement,ie我认为实现这一目标的最简单方法之一是用“break”语句替换“continue”,即

for ii in range(200):
 for jj in range(200, 400):
    ...block0...
    if something:
        break
 ...block1...       

For example, here is the easy code to see how exactly it goes on:例如,这里是简单的代码,可以查看它是如何进行的:

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")

We want to find something and then stop the inner iteration.我们想找到一些东西,然后停止内部迭代。 I use a flag system.我使用标志系统。

for l in f:
    flag = True
    for e in r:
        if flag==False:continue
        if somecondition:
            do_something()
            flag=False

Another way to deal with this kind of problem is to use Exception().处理此类问题的另一种方法是使用 Exception()。

for ii in range(200):
    try:
        for jj in range(200, 400):
            ...block0...
            if something:
                raise Exception()
    except Exception:
        continue
    ...block1...

For example:例如:

for n in range(1,4):
    for m in range(1,4):
        print n,'-',m

result:结果:

    1-1
    1-2
    1-3
    2-1
    2-2
    2-3
    3-1
    3-2
    3-3

Assuming we want to jump to the outer n loop from m loop if m =3:假设我们要从 m 循环跳到外层 n 循环,如果 m = 3:

for n in range(1,4):
    try:
        for m in range(1,4):
            if m == 3:
                raise Exception()            
            print n,'-',m
    except Exception:
        continue

result:结果:

    1-1
    1-2
    2-1
    2-2
    3-1
    3-2

Reference link: http://www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python参考链接: http : //www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python

I just did something like this.我只是做了这样的事情。 My solution for this was to replace the interior for loop with a list comprehension.我对此的解决方案是用列表理解替换内部 for 循环。

for ii in range(200):
    done = any([op(ii, jj) for jj in range(200, 400)])
    ...block0...
    if done:
        continue
    ...block1...

where op is some boolean operator acting on a combination of ii and jj.其中 op 是一些布尔运算符,作用于 ii 和 jj 的组合。 In my case, if any of the operations returned true, I was done.就我而言,如果任何操作返回 true,我就完成了。

This is really not that different from breaking the code out into a function, but I thought that using the "any" operator to do a logical OR on a list of booleans and doing the logic all in one line was interesting.这与将代码分解成函数实际上并没有什么不同,但我认为使用“any”运算符对布尔值列表执行逻辑 OR 并将逻辑全部放在一行中很有趣。 It also avoids the function call.它还避免了函数调用。

The best approach I know to continue an outer loop is using a Boolean that is scoped under the outer loop and breaking the inner one.我知道继续外循环的最佳方法是使用一个布尔值,该布尔值位于外循环下并破坏内循环。 Although, depending on the use case you may not break the inner loop, continuing an outer loop inside its inner loop implicitly suggests that you want to immediately jump to the first line of the outer loop and avoid any further execution in the inner one.尽管根据用例您可能不会中断内循环,但在其内循环内继续外循环暗示您希望立即跳转到外循环的第一行并避免在内循环中进一步执行。 That is why I added a break statement.这就是我添加break语句的原因。

for i in range(0, 6):
    should_continue = False

    for f in range(1, i * 2):
        print(f"f = {f}")
        if (not (f % 1337) or not (f % 7)):
            print(f"{f} can be divided, continue outer loop")
            should_continue = True
            # leaves inner loop
            break

    if(should_continue): continue
    # Outer loop's code goes here
    print(f'Reached outer loop\ni = {i}')

This approach avoids calling any functions and dealing with possible drawbacks.这种方法避免调用任何函数并处理可能的缺点。 Calling a function is known to be a rather expensive operation, specially for Games.众所周知,调用函数是一项相当昂贵的操作,特别是对于游戏而言。 Now imagine a deeply nested for loop that will run millions of times, wrapping it inside a function won't result in a smooth experience.现在想象一个深度嵌套的for循环,它将运行数百万次,将它包装在一个函数中不会带来流畅的体验。

Wrapping the loop inside an exception block is also a bad idea and will be way slower than functions.将循环包装在异常块内也是一个坏主意,并且会比函数慢。 This is because Python needs a lot of overhead to trigger the exceptions mechanism and later restore the runtime state, exceptions are designed to be used exceptionally.这是因为 Python 需要大量的开销来触发异常机制并稍后恢复运行时状态,因此异常被设计用于异常使用。 Taking that in mind, even some CPU optimizations such as speculative execution should not be applied to exception blocks and probably aren't.考虑到这一点,即使是一些 CPU 优化(例如speculative execution也不应该应用于异常块,而且可能也不是。

The only "problem" I found in this approach is that break will jump once outside of the inner loop, landing on continue , which, in turn, will jump one more time.我在这种方法中发现的唯一“问题”是break会在内循环之外跳一次,登陆continue ,而后者又会跳一次。 This, as opposed to a goto statement in C or JavaScript, is a bit more clumsy.与 C 或 JavaScript 中的 goto 语句相比,这有点笨拙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在使用 Python 发现异常后继续在 For 循环中进行下一次迭代 - Continuing to the next iteration in a For loop after an exception is found using Python 在外循环条件仍然适用的情况下继续内循环(python) - Continuing an inner loop while outer loop conditions still apply (python) 对于python中的循环,在每次迭代时初始化一个外部变量 - For loop in python initializes an outer variable on each iteration 在循环python中找到下一个迭代 - Find the next iteration in loop python Python,循环循环的下一次迭代 - Python, next iteration of the loop over a loop 在for循环期间引发异常,并在python中的下一个索引处继续 - Raising an exception during for loop and continuing at next index in python 如果满足某些条件,如何在继续下一次迭代之前保持在 for 循环中? - How do I stay within a for loop if certain conditions are met, before continuing to the next iteration? Python-For Loop if语句跳至Selenium中的下一个迭代 - Python - For Loop if statement skip to next iteration in Selenium 如何继续Python PDB中的下一个循环迭代? - How to continue to the next loop iteration in Python PDB? 如何在python中的for循环中跳过下一个迭代? - How to skip the next iteration during a for loop in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM