首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么for _ in范围(N)比in [""]*n慢?

为什么for _ in范围(N)比in [""]*n慢?
EN

Stack Overflow用户
提问于 2015-05-22 14:57:55
回答 2查看 3K关注 0票数 6

测试for _ in range(n)的替代方案(为了执行一些动作n时间,即使操作不依赖于n的值),我注意到还有另一个更快的模式,for _ in [""] * n

例如:

代码语言:javascript
复制
timeit('for _ in range(10^1000): pass', number=1000000)

返回16.4秒;

然而,

代码语言:javascript
复制
timeit('for _ in [""]*(10^1000): pass', number=1000000)

需要10.7秒。

为什么在Python3中[""] * 10^1000range(10^1000)快得多?

使用Python3.3完成的所有测试

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-22 16:30:30

range()上迭代时,为0到n之间的所有整数生成对象;这需要(很小)的时间,即使使用small integers having been cached也是如此。

另一方面,[None] * n上的循环生成对1个对象的n引用,创建该列表的速度要快一些。

然而,range()对象使用的内存要少得多,启动时的可读性也更强,这就是为什么人们更喜欢使用它。大多数代码不必从性能中挤出最后一滴。

如果需要这样的速度,可以使用不需要内存的自定义迭代,使用带有第二个参数的itertools.repeat()

代码语言:javascript
复制
from itertools import repeat

for _ in repeat(None, n):

至于你的计时测试,有一些问题。

首先,您在['']*n定时循环中出错;您没有嵌入两个引号,而是连接了两个字符串并生成了一个空列表。

代码语言:javascript
复制
>>> '['']*n'
'[]*n'
>>> []*100
[]

在迭代中,这将是无与伦比的,因为您已经迭代了0次。

您也没有使用大数字;^是二进制XOR运算符,而不是power运算符:

代码语言:javascript
复制
>>> 10^1000
994

这意味着您的测试遗漏了创建大量空值列表所需的时间。

使用更好的数字和None可以为您提供:

代码语言:javascript
复制
>>> 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
票数 10
EN

Stack Overflow用户

发布于 2015-05-22 16:14:00

你的问题是你不正确地给timeit喂食。

您需要给出包含timeit语句的字符串。如果你这样做了

代码语言:javascript
复制
stmt = 'for _ in ['']*100: pass'

看看stmt的值。方括号内的引号字符与字符串分隔符相匹配,因此它们被Python解释为字符串分隔符。由于Python连接相邻的字符串文本,您将看到真正拥有的与'for _ in [' + ']*100: pass'相同,这将为您提供'for _ in []*100: pass'

所以你的“超快”循环只是在空列表上循环,而不是100个元素的列表。例如,试试你的测试,

代码语言:javascript
复制
stmt = 'for _ in [""]*100: pass'
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30399987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档