Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:继续外循环中的下一个迭代_Python_Loops - Fatal编程技术网

Python:继续外循环中的下一个迭代

Python:继续外循环中的下一个迭代,python,loops,Python,Loops,我想知道是否有任何内置方法可以在python的外部循环中继续进行下一次迭代。例如,考虑代码: for ii in range(200): for jj in range(200, 400): ...block0... if something: continue ...block1... 我希望这个continue语句退出jj循环,转到ii循环中的下一项。我可以用其他方式实现这个逻辑(通过设置一个标志变量),但是有没有一个

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

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            continue
    ...block1...
我希望这个continue语句退出jj循环,转到ii循环中的下一项。我可以用其他方式实现这个逻辑(通过设置一个标志变量),但是有没有一个简单的方法来实现这个逻辑,或者这像是要求太多

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

Break
将中断内部循环,而block1将不会执行(仅当内部循环正常退出时才会运行)。

在其他语言中,您可以标记循环并从标记的循环中断。但是:

然而,我拒绝了它,因为代码太复杂了 需要此功能的情况非常罕见。在大多数情况下,现有的 产生干净代码的变通方法,例如使用“return”。 虽然我确信有一些(罕见的)真实案例表明 代码将受到重构的影响,从而可能使用 返回,这由两个问题抵消:

  • 语言的复杂性永久性地增加了。这不影响 只有所有的Python实现,还有所有的源代码分析工具, 当然还有该语言的所有文档

  • 我预计该功能将被滥用得更多 正确使用,导致代码清晰度净下降(跨 以后编写的所有Python代码)。懒惰的程序员无处不在, 在你意识到这一点之前,你的手上有一团令人难以置信的混乱 无法理解的代码


  • 因此,如果这就是你所希望的,那么你就走运了,但是看看其他答案中的一个,因为有很多好的选择。

    我认为你可以这样做:

    for ii in range(200):
        restart = False
        for jj in range(200, 400):
            ...block0...
            if something:
                restart = True
                break
        if restart:
            continue
        ...block1...
    
    在一般情况下,当您有多个级别的循环且
    break
    对您不起作用时(因为您希望继续上面的一个循环,而不是当前循环正上方的一个),您可以执行以下操作之一

    将要退出的循环重构为函数 缺点是您可能需要向该新函数传递一些以前在作用域中的变量。您可以将它们作为参数传递,使它们成为对象上的实例变量(如果有意义的话,为这个函数创建一个新对象),或者全局变量,单例,等等(ehm,ehm)

    或者您可以将
    internal
    定义为一个嵌套函数,让它只捕获所需的内容(可能较慢?)

    使用异常 从理论上讲,这就是异常的用途,必要时中断结构化编程构建块(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
    
    为此创建一个特殊的异常类,这样您就不会冒意外地使某些其他异常静音的风险

    完全是另一回事
    我确信还有其他解决方案。

    处理此类问题的另一种方法是使用Exception()

    例如:

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

        1-1
        1-2
        1-3
        2-1
        2-2
        2-3
        3-1
        3-2
        3-3
    
        1-1
        1-2
        2-1
        2-2
        3-1
        3-2
    
    假设我们想要从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
    
    结果:

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

    参考链接:

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

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

    我只是做了这样的事。我的解决方案是用列表替换内部for循环

    for ii in range(200):
        done = any([op(ii, jj) for jj in range(200, 400)])
        ...block0...
        if done:
            continue
        ...block1...
    
    其中op是作用于ii和jj组合的布尔运算符。在我的例子中,如果任何一个操作返回true,我就完成了


    这与将代码分解成函数并没有什么不同,但我认为使用“any”操作符在布尔值列表上执行逻辑OR,并在一行中执行所有逻辑是有趣的。它还避免了函数调用。

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

    for ii in range(200):
     for jj in range(200, 400):
        ...block0...
        if something:
            break
     ...block1...       
    
    例如,下面是一个简单的代码,可以查看它到底是如何运行的:

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

    我所知道的继续外循环的最佳方法是使用一个范围在外循环下的布尔值,然后断开内循环。尽管,根据用例的不同,您可能不会中断内部循环,但在其内部循环中继续外部循环暗示您希望立即跳转到外部循环的第一行,并避免在内部循环中进一步执行。这就是为什么我添加了一个
    break
    语句

    范围(0,6)内的i的
    :
    是否继续=错误
    对于范围(1,i*2)内的f:
    打印(f“f={f}”)
    如果(不是(f%1337)或不是(f%7)):
    打印(f“{f}可以分割,继续外循环”)
    是否继续=真
    #叶内环
    打破
    如果(应该继续):继续
    #外循环的代码在这里
    打印(f'到达外循环\ni={i}')
    
    这种方法避免了调用任何函数和处理可能的缺点。众所周知,调用函数是一项相当昂贵的操作,特别是在游戏中。现在想象一个深入嵌套的
    for
    循环将运行数百万次,将其包装在函数中不会带来平滑的体验

    将循环包装在异常块中也是一个坏主意,并且比函数慢得多。这是因为Python需要大量开销来触发异常机制,然后恢复运行时状态,异常被设计为异常使用。考虑到这一点,即使是一些CPU优化,例如
    推测执行
    ,也不应该应用于异常块,而且可能不会

    我发现的唯一“问题”是
    for ii in range(200):
     for jj in range(200, 400):
        ...block0...
        if something:
            break
     ...block1...       
    
    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")