使用continue替代if-elif
假设我正在遍历一个输入列表,这些输入可以是两个字典中的键。
for key in inputs:
if key in status_msg.keys():
print status_msg[key]
elif key in error_msg.keys():
print error_msg[key]
我在阅读关于 continue
命令的内容,可以在这里找到,还有这里,我在想这样做是否会更好:
for key in inputs:
if key in status_msg.keys():
print status_msg[keys]
continue
if key in error_msg.keys():
print error_msg[key]
使用 continue
代替 if elif
会有什么好处,还是说效果是一样的呢?
4 个回答
其实是一样的。如果你想知道它们之间有没有性能上的差别,可以通过多次循环或者用一些样本数据来测试一下,看看结果如何。
在你给的例子中,虽然这在某种程度上是个人喜好,但我更倾向于使用 if / elif
,因为我觉得这样更清楚地表达了你想要打印两个值中的一个的逻辑。
continue
更适合用在较大的循环中,这种情况下某些循环的情况需要完全跳过(但这些情况太复杂,无法简单地用范围或列表推导来控制循环),或者某些循环的情况需要处理得少一些,因此应该提前退出。
你给的例子中的问题是,如果你在循环的末尾添加更多通用代码,可能不太明显当 key
在 status_msgs
中时,这段代码不会被执行。
如果你忘记写一个 continue
,那么发现和修复这个错误会比不小心用 if
代替 elif
更困难。因为 if
和 elif
在它们所包含的缩进块中很明显,更容易被注意到。而且,如果你添加了一个新的代码块,很容易忘记在最后一个代码块的末尾加上 continue
。使用 continue
的问题和 C 语言中的 switch 语句的问题是类似的,很多 C 语言程序员都能讲述忘记在 switch
语句中加 break
的恐怖故事。
从性能上来说,几乎不会有明显的差别。因为这两个代码片段是等价的,差别主要在于字节码编译器的实现细节和它生成的跳转指令。
一个更显著的改进是将像下面这样的测试:
if key in status_msg.keys():
替换为:
if key in status_msg:
检查某个东西是否在字典的 keys
中,需要先创建一个键的列表,然后逐个检查。而直接检查这个东西是否在字典中则是快速的哈希查找。
在你的具体例子中,控制流程是一样的。如果代码没有变化,那就没有区别。它甚至可能编译成相同的字节码。
不过,elif
版本更清楚地表达了你的意图。你是在告诉阅读代码的人,你期望在 status_msg
中找到 key
,如果没有找到,你希望在 error_msg
中找到它。对我来说,其他部分的代码似乎只会在 status_msg
没有内容时才填充 error_msg
。
而 continue
版本就显得有些模糊。error_msg
在每种情况下都有内容吗?continue
版本也不太适合未来的需求:如果你想在打印之后做其他事情,不管 key
是在哪里找到的呢?如果考虑这段代码:
for key in inputs:
if key in status_msg.keys():
print status_msg[keys]
continue
if key in error_msg.keys():
print error_msg[key]
do_something()
那么 do_something()
只会在 key
不在 status_msg
中时执行。条件判断是不对称的;一个会中断循环,另一个则会继续执行后面的代码。这对后面阅读代码的人来说可能不太明显,尤其是当条件判断包含更复杂的逻辑或更多行时。
我认为 elif
版本更好:它适合未来的需求,清楚表达了你的意图,并且是对称的。性能可能是一样的,即使不一样,那也只是微不足道的差别。