Python:在外层循环中继续下一次迭代
我想知道在Python中有没有内置的方法可以让外层循环继续到下一次迭代。比如,看看下面这段代码:
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
continue
...block1...
我希望这个continue语句能让jj循环结束,然后直接跳到ii循环的下一个项目。我可以通过设置一个标志变量来实现这个逻辑,但有没有更简单的方法呢?还是说这要求太高了?
9 个回答
在其他编程语言中,你可以给循环加个标签,然后从这个标签的循环中跳出来。Python的一个提案(PEP 3136)曾建议在Python中加入这个功能,但Guido拒绝了这个提案:
他表示,拒绝这个提案的原因是,代码复杂到需要这个功能的情况非常少见。在大多数情况下,有现成的解决办法可以写出更简洁的代码,比如使用'return'。虽然我相信确实有一些(少见的)真实案例,重构代码后会影响代码的清晰度,但这可以通过两个问题来抵消:
这个功能会给语言增加复杂性,且是永久性的。这不仅影响所有Python的实现,还会影响每一个源代码分析工具,当然也包括所有的语言文档。
我预计这个功能会被滥用的情况会比正确使用的情况多,导致代码的清晰度整体下降(在今后所有写的Python代码中衡量)。懒惰的程序员随处可见,没过多久,你就会发现手头的代码变得一团糟,根本看不懂。
所以如果你希望有这个功能,那你可能要失望了,不过可以看看其他答案,那里面有不错的选择。
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
break
else:
...block1...
Break
这个指令会让里面的循环停止,也就是说,block1 这部分代码不会被执行(只有当里面的循环正常结束时,block1 才会运行)。
for i in ...:
for j in ...:
for k in ...:
if something:
# continue loop i
在一般情况下,当你有多个循环层级,而 break
不能满足你的需求时(因为你想继续上面的某个循环,而不是直接上面的那个),你可以尝试以下几种方法。
把你想跳出的循环重构成一个函数
def inner():
for j in ...:
for k in ...:
if something:
return
for i in ...:
inner()
这样做的缺点是,你可能需要把一些之前在作用域内的变量传递给这个新函数。你可以选择把它们作为参数传递,或者把它们变成对象的实例变量(如果有必要,可以为这个函数创建一个新对象),或者使用全局变量、单例模式等等(咳咳)。
另外,你也可以把 inner
定义为一个嵌套函数,让它直接捕获所需的变量(可能会慢一些?)
for i in ...:
def inner():
for j in ...:
for k in ...:
if something:
return
inner()
使用异常
从哲学上讲,这就是异常的作用,当需要时打断程序的正常流程(比如 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
为此创建一个特殊的异常类,这样你就不会意外地抑制其他异常。
完全不同的其他方法
我相信还有其他解决方案。