【发布时间】:2016-11-12 02:48:53
【问题描述】:
我对何时应该在函数中使用生成器以及何时应该只使用列表很感兴趣,因此我对过滤器和列表推导进行了一些测试。
>>> timeit.timeit('list(filter(lambda x: x%10, range(10)))')
3.281250655069016
>>> timeit.timeit('[i for i in range(10) if i%10 != 0]')
2.6070076799951494
>>> timeit.timeit('filter(lambda x: x%10, range(10))')
0.7457015149993822
然后我尝试使用 range(100):
>>> timeit.timeit('list(filter(lambda x: x%10, range(100)))')
27.73180518404115
>>> timeit.timeit('[i for i in range(100) if i%10 != 0]')
18.659852175973356
>>> timeit.timeit('filter(lambda x: x%10, range(100))')
0.7294546449556947
为什么从生成器对象创建一个列表比简单地创建一个列表要长这么多?如果我需要多次访问该列表,使用列表推导而不是从生成器对象创建列表会更好吗?
【问题讨论】:
-
@PadraicCunningham 好吧,他们不是都得到
next被多次调用吗?但是,是的,你调用它的次数越多,完成序列迭代所需的时间就越长。 -
@Dandré,
[i for i in range(10) if i%10 != 0],与列表本身相关的下一个调用在哪里? -
@PadraicCunningham range() 是一个具有隐式调用
next的生成器 -
在旁注中,
[i for i in range(100) if i%10 != 0]中的!= 0是多余的。if i%10够用而且速度更快。 -
@Tanmay:它不是生成器。生成器是一种非常特殊的迭代器类型,它基于暂停和恢复 Python 函数的执行,由生成器表达式或使用
yield创建。该术语不是指任意惰性迭代。
标签: python list python-3.x generator timeit