在我的代码中,我经常比较if a == b or a == c or a == d:
这样的比较。在某些时候,我发现如果值不可清除,可以很容易地将这些缩短为if a in {b, c, d}:
或if a in (b, c, d):
。但是,我从来没有在其他任何人的代码中看到过这样的结构。这可能是因为:
==
方式较慢。==
方式更加pythonic。in
方式。是什么原因,如果有的话?
答案 0 :(得分:4)
对于简单值(即不是表达式或NaN
s),if a == b or a == c
和if a in <iterable of b and c>
是等价的。
如果值是可清除的,最好将in
与 set literal 一起使用,而不是使用元组或列表文字:
if a in {b, c}: ...
CPython的peephole optimiser通常能够用缓存的frozenset()
对象替换它,对集合的成员资格测试是O(1)操作。
答案 1 :(得分:2)
Performancewise:&#34; in&#34;更好
timeit.timeit("pub='1'; pub == 1 or pub == '1'")
0.07568907737731934
timeit.timeit("pub='1'; pub in[1, '1']")
0.04272890090942383
timeit.timeit("pub=1; pub == 1 or pub == '1'")
0.07502007484436035
timeit.timeit("pub=1; pub in[1, '1']")
0.07035684585571289
另外&#34;在&#34;确保代码不重复== 1或a == 2是重复。 而且阅读不好。 &#34;在&#34;只是让它更容易理解。这是简单而优雅的代码实践的案例之一。简而言之,我们(应该)使用&#34;&#34;更常见的是,如果我们还没有使用它。
答案 2 :(得分:2)
我很想知道直接比较与阵列检查之间的时间差异。
结论:构建阵列的成本并不是免费的,在考虑速度差异时必须考虑到这一点。
如果在比较时正在构造阵列,则技术上比简单比较慢。因此,简单的比较可以更快地进出循环。
如果数组已经构建,那么在一个大循环中检查数组比进行简单比较要快得多。
$ speed.py
inarray x 1000000: 0.277590343844
comparison x 1000000: 0.347808290754
makearray x 1000000: 0.408771123295
import timeit
NUM = 1000000
a = 1
b = 2
c = 3
d = 1
array = {b,c,d}
tup = (b,c,d)
lst = [b,c,d]
def comparison():
if a == b or a == c or a == d:
pass
def makearray():
if a in {b, c, d}:
pass
def inarray():
if a in array:
pass
def maketuple():
if a in (b,c,d):
pass
def intuple():
if a in tup:
pass
def makelist():
if a in [b,c,d]:
pass
def inlist():
if a in lst:
pass
def time_all(funcs, params=None):
timers = []
for func in funcs:
if params:
tx = timeit.Timer(lambda: func(*params))
else:
tx = timeit.Timer(lambda: func())
timers.append([func, tx.timeit(NUM)])
for func, speed in sorted(timers, key=lambda x: x[1]):
print "{fn:<25} x {n}: ".format(fn=func.func_name, n=NUM), speed
print ""
return
time_all([comparison,
makearray,
inarray,
intuple,
maketuple,
inlist,
makelist
],
)
这并没有完全回答你的问题,为什么你不经常看到使用的比较。我会猜测,但它可能是1,2,4的组合,以及作者需要的情况写下那段特殊的代码。
我个人根据情况亲自使用这两种方法。选择通常取决于速度或简单性。
编辑:
@ bracco23是对的,使用元组vs阵列vs列表会有一些细微的差别会改变时间。
$ speed.py
inarray x 1000000: 0.260784980761
intuple x 1000000: 0.288696420718
inlist x 1000000: 0.311479982167
maketuple x 1000000: 0.356532747578
comparison x 1000000: 0.360010093964
makearray x 1000000: 0.41094386108
makelist x 1000000: 0.433603059099