繁体   English   中英

python中的最佳方法是什么:if语句中的OR或IN?

[英]What is the best approach in python: multiple OR or IN in if statement?

python中的最佳方法是什么:if语句中的ORIN 考虑性能和最佳实践。

if cond == '1' or cond == '2' or cond == '3' or cond == '4' (etc...) :

要么

if cond in ['1','2','3','4']:

谢谢。

最好的方法是使用set

if cond in {'1','2','3','4'}:

因为集合中的成员资格测试为O(1)(不变成本)。

其他两种方法的复杂度是相同的。 只是固定成本的差异。 列表in待测和链or链短路; 找到匹配项后立即终止。 一种使用字节码跳转序列(如果为True则跳转到末尾),另一种使用C循环,如果值匹配则使用提前退出。 在最坏的情况下,如果cond与序列中的元素匹配,则两种方法都必须先检查所有元素,然后才能返回False 在这两者之中,我每天都会选择in测试,因为它更具可读性。

彼得的回答在大多数情况下是最好的。 但是,在您的特定情况下,我不会inor使用in而是这样做:

if 0 < int(cond) < 5:

如果cond为'1','2','3'或'4',则if块将运行。 这样做的好处是,它比其他答案要短。

这实际上取决于Python的版本。 Python 2.7中,字节码中没有设置常量,因此在Python 2中,如果使用固定常量,则较小的一组值将使用元组:

if x in ('2', '3', '5', '7'):
    ...

元组是一个常数:

>>> dis.dis(lambda: item in ('1','2','3','4'))
  1           0 LOAD_GLOBAL              0 (item)
              3 LOAD_CONST               5 (('1', '2', '3', '4'))
              6 COMPARE_OP               6 (in)
              9 RETURN_VALUE

Python也足够聪明,可以将Python 2.7上的常量列表优化为元组:

>>> dis.dis(lambda: item in ['1','2','3','4'])
  1           0 LOAD_GLOBAL              0 (item)
              3 LOAD_CONST               5 (('1', '2', '3', '4'))
              6 COMPARE_OP               6 (in)
              9 RETURN_VALUE        

但是Python 2.7字节码(和编译器)缺乏对常量集的支持:

>>> dis.dis(lambda: item in {'1','2','3','4'})
  1           0 LOAD_GLOBAL              0 (item)
              3 LOAD_CONST               1 ('1')
              6 LOAD_CONST               2 ('2')
              9 LOAD_CONST               3 ('3')
             12 LOAD_CONST               4 ('4')
             15 BUILD_SET                4
             18 COMPARE_OP               6 (in)
             21 RETURN_VALUE        

这意味着需要为每个测试重建if条件。


但是在Python 3.4中 ,字节码支持设置常量。 代码在那里评估为:

>>> dis.dis(lambda: item in {'1','2','3','4'})
  1           0 LOAD_GLOBAL              0 (item)
              3 LOAD_CONST               5 (frozenset({'4', '2', '1', '3'}))
              6 COMPARE_OP               6 (in)
              9 RETURN_VALUE

至于多重or代码,它会产生完全可怕的字节码:

>>> dis.dis(lambda: item == '1' or item == '2' or item == '3' or item == '4')
  1           0 LOAD_GLOBAL              0 (item)
              3 LOAD_CONST               1 ('1')
              6 COMPARE_OP               2 (==)
              9 JUMP_IF_TRUE_OR_POP     45
             12 LOAD_GLOBAL              0 (item)
             15 LOAD_CONST               2 ('2')
             18 COMPARE_OP               2 (==)
             21 JUMP_IF_TRUE_OR_POP     45
             24 LOAD_GLOBAL              0 (item)
             27 LOAD_CONST               3 ('3')
             30 COMPARE_OP               2 (==)
             33 JUMP_IF_TRUE_OR_POP     45
             36 LOAD_GLOBAL              0 (item)
             39 LOAD_CONST               4 ('4')
             42 COMPARE_OP               2 (==)
        >>   45 RETURN_VALUE        

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM