繁体   English   中英

如果a == b或a == c:vs if in {b,c}:

[英]if a == b or a == c: vs if a in {b, c}:

在我的代码中,我过去常常进行比较,如if a == b or a == c or a == d:相当频繁。 在某些时候,我发现if a in {b, c, d}:或者if a in (b, c, d): ,这些可以很容易地缩短到if a in (b, c, d):如果值不可清除。 但是,我从来没有在别人的代码中看到过这样的结构。 这可能是因为:

  1. ==方式比较慢。
  2. ==方式更加pythonic。
  3. 他们实际上做了微妙的不同的事情。
  4. 我偶然没有看过任何需要的代码。
  5. 我已经看过了,只是忽略或忘记了它。
  6. 人们不应该像这样进行比较,因为其他人的代码应该更好。
  7. 没有人想到了in除我之外的方式。

这是什么原因,是吗?

对于简单值(即非表达式或NaN s), if a == b or a == c并且if a in <iterable of b and c>是等价的。

如果值是哈希的,最好是用in文字而不是元组或列表文字一套

if a in {b, c}: ...

CPython的窥孔优化器通常能够用缓存的frozenset()对象替换它,对集合的成员资格测试是O(1)操作。

Performancewise:“in”更好

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

同样“in”确保代码不重复== 1或a == 2是重复。 而且阅读不好。 “in”只是让它更容易理解。 这是简单而优雅的代码实践的案例之一。 简而言之,如果我们还没有使用它,我们应该更频繁地使用“in”。

我很想知道直接比较与阵列检查之间的时间差异。

结论: 构建阵列的成本并不是免费的,在考虑速度差异时必须考虑到这一点。

如果在比较时构造阵列,则技术上比简单比较慢。 因此,简单的比较可以更快地进出循环。

也就是说,如果已经构造了数组,那么在一个大循环中检查数组比进行简单比较更快。

$ 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

暂无
暂无

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

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