使用 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
相比,更难发现和纠正错误。 if
s 和 elif
s 从它们包含的缩进块中突出,使它们更容易被注意到。此外,如果您添加一个新块,很容易忘记在最后一个块的末尾添加continue
。使用continue
的问题与使用C switch 语句的问题本质上是相同的,几代C 程序员可以告诉你关于忘记break
而不是switch
es 的恐怖故事。
就性能而言,不太可能有任何可衡量的差异。由于两个代码 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
更适合较大的循环,其中某些循环实例应该完全跳过(但这些实例太复杂,无法清楚地编程到用于控制循环的范围或列表理解中)或某些实例循环需要更少的处理,因此应该提前退出。
您给出的示例中的问题是,如果您稍后在循环末尾添加更多通用代码,则当key
在status_msgs
时可能不会立即明显地执行该代码.
【讨论】:
【参考方案4】:同样的事情。如果存在任何性能差异,您可以使用足够的循环或样本数据对其进行分析以进行比较。
【讨论】:
以上是关于使用 continue 代替 if-elif的主要内容,如果未能解决你的问题,请参考以下文章
"no statement" 和 continue 之间的区别
3-21 lambda,try,continue&break, copy,threading
[paper reading] C-MIL: Continuation Multiple Instance Learning for Weakly Supervised Object Detectio