为什么“枚举”比“xrange + lst [i]”慢?
>>> from timeit import Timer
>>> lst = [1,2,3,0,1,2]*1000
>>> setup = 'from __main__ import lst'
>>> s1 = """
for i in range(len(lst)):
elem = lst[i]
"""
>>> s2 = """
for i in xrange(len(lst)):
elem = lst[i]
"""
>>> s3 = """
for i, v in enumerate(lst):
elem = v
"""
>>> t1 = Timer(s1, setup); t2 = Timer(s2, setup); t3 = Timer(s3, setup)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.9263118636586494, 1.6119261665937992, 1.9606022553145719)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.93520258859715, 1.6145745478824836, 1.9529405971988041)
编辑: 我记得为什么
for i, v in enumerate(lst):
elem = i, v
慢于for i in xrange(len(lst)):
elem = i, lst[i]
答案 0 :(得分:15)
如果你测量得当,你会发现基本上没有区别(在这个例子中,枚举在微观上比xrange快,但在噪音范围内):
$ python -mtimeit -s'lst=[1,2,3,0,1,2]*1000' 'for i in xrange(len(lst)): elem=lst[i]'
1000 loops, best of 3: 480 usec per loop
$ python -mtimeit -s'lst=[1,2,3,0,1,2]*1000' 'for i, elem in enumerate(lst): pass'
1000 loops, best of 3: 473 usec per loop
(顺便说一句,我总是建议在shell提示符下使用timeit
,不要在代码内或在解释器提示符下使用,只是因为输出格式和可用性非常好,单位为衡量时间和一切)。
在您的代码中,您在枚举案例中有一个额外的分配:您在for
标题子句中将列表项分配给v,然后再次将v
分配给elem
;而在xrange情况下,您只需将项目分配一次,即elem
。在我的情况下,我当然也只分配一次,当然;你为什么要分配多次?!无论你在循环体中使用elem
和i
做什么,你都可以在我测量的两种形式中完全相同,只是没有你的枚举案例所具有的冗余。
答案 1 :(得分:5)
可能是因为你已经步履蹒跚enumerate
。试试这个:
>>> s3 = """
for i, elem in enumerate(lst):
pass
"""
更新在亚力克特未提及的shell提示符下使用timeit
的两个额外原因:
(1)为你做“最好的N” (2)为你获得有意义的结果需要多少次迭代。