使用 continue 代替 if-elif

Posted

技术标签:

【中文标题】使用 continue 代替 if-elif【英文标题】:Using continue instead of if-elif 【发布时间】:2014-03-20 17:18:06 【问题描述】:

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

  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 命令 here 和 here 的信息,我想知道这是否是一种更好的方法:

  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 会有什么好处,还是完全一样?

【问题讨论】:

不,您只是添加了另一行。无论如何,循环将在那时继续。 它做同样的事情并且稍长一些,所以我会说这里没有任何好处! 不使用elif 的预期好处是什么?在提出的最小用例中,elif 很简单,而continue 则不那么简单。出于某些目的使用 continue 是可以的,但是,如果您想这样做,原因是什么? 【参考方案1】:

如果您忘记了continue,与不小心使用if 而不是elif 相比,更难发现和纠正错误。 ifs 和 elifs 从它们包含的缩进块中突出,使它们更容易被注意到。此外,如果您添加一个新块,很容易忘记在最后一个块的末尾添加continue。使用continue 的问题与使用C switch 语句的问题本质上是相同的,几代C 程序员可以告诉你关于忘记break 而不是switches 的恐怖故事。

就性能而言,不太可能有任何可衡量的差异。由于两个代码 sn-ps 是等价的,所以区别在于字节码编译器的实现细节和它产生的跳转指令。

替换测试将带来更显着的改进

if key in status_msg.keys():

if key in status_msg:

测试某个东西是否在字典的keys 中需要创建一个键列表,然后一个一个地检查它们。直接测试事物是否在 dict 中是一种快速的哈希查找。

【讨论】:

【参考方案2】:

在您的具体示例中,控制流程将是相同的。如果代码保持不变,就没有区别。它甚至可以编译成相同的字节码。

不过,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 版本更胜一筹:它面向未来,表明您的意图,并且是对称的。性能可能是相同的,即使不是,它在名义上也是不同且无关的。

【讨论】:

【参考方案3】:

在您给出的示例中,虽然在某种程度上这是一个偏好问题,但我更喜欢if / elif,因为我相信它更清楚地表达了您想要打印两个值之一的逻辑。

continue 更适合较大的循环,其中某些循环实例应该完全跳过(但这些实例太复杂,无法清楚地编程到用于控制循环的范围或列表理解中)或某些实例循环需要更少的处理,因此应该提前退出。

您给出的示例中的问题是,如果您稍后在循环末尾添加更多通用代码,则当keystatus_msgs 时可能不会立即明显地执行该代码.

【讨论】:

【参考方案4】:

同样的事情。如果存在任何性能差异,您可以使用足够的循环或样本数据对其进行分析以进行比较。

【讨论】:

以上是关于使用 continue 代替 if-elif的主要内容,如果未能解决你的问题,请参考以下文章

"no statement" 和 continue 之间的区别

3-21 lambda,try,continue&break, copy,threading

在 C++ 中的函数内继续而不是返回

[paper reading] C-MIL: Continuation Multiple Instance Learning for Weakly Supervised Object Detectio

return false

for Each篇