测试for _ in range(n)的替代方案(为了执行一些动作n时间,即使操作不依赖于n的值),我注意到还有另一个更快的模式,for _ in [""] * n。
例如:
timeit('for _ in range(10^1000): pass', number=1000000)返回16.4秒;
然而,
timeit('for _ in [""]*(10^1000): pass', number=1000000)需要10.7秒。
为什么在Python3中[""] * 10^1000比range(10^1000)快得多?
使用Python3.3完成的所有测试
发布于 2015-05-22 16:30:30
在range()上迭代时,为0到n之间的所有整数生成对象;这需要(很小)的时间,即使使用small integers having been cached也是如此。
另一方面,[None] * n上的循环生成对1个对象的n引用,创建该列表的速度要快一些。
然而,range()对象使用的内存要少得多,启动时的可读性也更强,这就是为什么人们更喜欢使用它。大多数代码不必从性能中挤出最后一滴。
如果需要这样的速度,可以使用不需要内存的自定义迭代,使用带有第二个参数的itertools.repeat():
from itertools import repeat
for _ in repeat(None, n):至于你的计时测试,有一些问题。
首先,您在['']*n定时循环中出错;您没有嵌入两个引号,而是连接了两个字符串并生成了一个空列表。
>>> '['']*n'
'[]*n'
>>> []*100
[]在迭代中,这将是无与伦比的,因为您已经迭代了0次。
您也没有使用大数字;^是二进制XOR运算符,而不是power运算符:
>>> 10^1000
994这意味着您的测试遗漏了创建大量空值列表所需的时间。
使用更好的数字和None可以为您提供:
>>> from timeit import timeit
>>> 10 ** 6
1000000
>>> timeit("for _ in range(10 ** 6): pass", number=100)
3.0651066239806823
>>> timeit("for _ in [None] * (10 ** 6): pass", number=100)
1.9346517859958112
>>> timeit("for _ in repeat(None, 10 ** 6): pass", 'from itertools import repeat', number=100)
1.4315521717071533发布于 2015-05-22 16:14:00
你的问题是你不正确地给timeit喂食。
您需要给出包含timeit语句的字符串。如果你这样做了
stmt = 'for _ in ['']*100: pass'看看stmt的值。方括号内的引号字符与字符串分隔符相匹配,因此它们被Python解释为字符串分隔符。由于Python连接相邻的字符串文本,您将看到真正拥有的与'for _ in [' + ']*100: pass'相同,这将为您提供'for _ in []*100: pass'。
所以你的“超快”循环只是在空列表上循环,而不是100个元素的列表。例如,试试你的测试,
stmt = 'for _ in [""]*100: pass'https://stackoverflow.com/questions/30399987
复制相似问题