在检查相等性时,以下两种方式的速度和功能是否有实际差异:
number = 'one'
if number == 'one' or number == 'two':
对比。
number = 'one'
if number in ['one', 'two']:
在检查相等性时,以下两种方式的速度和功能是否有实际差异:
number = 'one'
if number == 'one' or number == 'two':
对比。
number = 'one'
if number in ['one', 'two']:
in
可能会更快,因为(极其有限的)优化器将其转换为一次性加载的常量tuple
,从而将执行的字节码工作减少到两个便宜的加载和单个比较操作/条件跳转,而链接的or
包含每个测试的两个便宜的加载和一个比较操作/条件跳转。number
是更复杂的表达式,则通常可以获得优势;my_expensive_function() in (...)
显然优于my_expensive_function() == A or my_expensive_function() == B
,因为前者只计算一次值。tuple
中的值不是常量文字,特别是如果命中将在早期值上普遍发生,则in
通常会更昂贵(因为它必须每次都创建用于测试的序列,即使最终只测试第一个值)。谈到功能性 - 不,这两种方法通常是不同的:请参见https://dev59.com/q57ha4cB1Zd3GeqPnbQo#41957167
NaN
的怪异行为值得注意,但它并不是一个“普遍的差异”(NaN
几乎是唯一的在比较时与自身不相等的数据类型)。就功能而言,number in ['one', 'two']
等价于(除了值加载次数) number is 'one' or number == 'one' or number is 'two' or number == 'two'
。对于字符串来说,这只是性能提升,而非行为上的差异。 - ShadowRanger__eq__
,其中可以包括非平凡计算或关注相似对象是否相等 - 在这种情况下,检查is
可能会改变行为。同样,对于重写__contains__
的自定义容器(但我认为这是较少见的情况),也是如此。 - Eugene Primako
timeit
吗?发生了什么?如果number='two'
或为false-y的情况下会怎样?如果性能很重要,为什么不使用in {'one', 'two'}
? - jonrsharpeset
才有帮助;对于两个值,set
是无济于事的。而且在这种情况下,OP 正在询问 Python 2,它不会优化set
字面量中的测试,因此每次都必须从头开始重建set
,即使所有值都是字面常量,这将保证比创建全局常量的集合慢。在 Python 3 中,有一种优化方法可以用一个常量frozenset
替换此上下文中的常量set
字面量,因此可以在某些情况下节省时间,但在 Py2 中则不行。 - ShadowRanger