使用continue替代if-elif

1 投票
4 回答
2235 浏览
提问于 2025-04-17 23:10

假设我正在遍历一个输入列表,这些输入可以是两个字典中的键。

  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 个回答

0

其实是一样的。如果你想知道它们之间有没有性能上的差别,可以通过多次循环或者用一些样本数据来测试一下,看看结果如何。

1

在你给的例子中,虽然这在某种程度上是个人喜好,但我更倾向于使用 if / elif,因为我觉得这样更清楚地表达了你想要打印两个值中的一个的逻辑。

continue 更适合用在较大的循环中,这种情况下某些循环的情况需要完全跳过(但这些情况太复杂,无法简单地用范围或列表推导来控制循环),或者某些循环的情况需要处理得少一些,因此应该提前退出。

你给的例子中的问题是,如果你在循环的末尾添加更多通用代码,可能不太明显当 keystatus_msgs 中时,这段代码不会被执行。

5

如果你忘记写一个 continue,那么发现和修复这个错误会比不小心用 if 代替 elif 更困难。因为 ifelif 在它们所包含的缩进块中很明显,更容易被注意到。而且,如果你添加了一个新的代码块,很容易忘记在最后一个代码块的末尾加上 continue。使用 continue 的问题和 C 语言中的 switch 语句的问题是类似的,很多 C 语言程序员都能讲述忘记在 switch 语句中加 break 的恐怖故事。

从性能上来说,几乎不会有明显的差别。因为这两个代码片段是等价的,差别主要在于字节码编译器的实现细节和它生成的跳转指令。

一个更显著的改进是将像下面这样的测试:

if key in status_msg.keys():

替换为:

if key in status_msg:

检查某个东西是否在字典的 keys 中,需要先创建一个键的列表,然后逐个检查。而直接检查这个东西是否在字典中则是快速的哈希查找。

5

在你的具体例子中,控制流程是一样的。如果代码没有变化,那就没有区别。它甚至可能编译成相同的字节码。

不过,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 版本更好:它适合未来的需求,清楚表达了你的意图,并且是对称的。性能可能是一样的,即使不一样,那也只是微不足道的差别。

撰写回答