我对何时应该在函数中使用生成器感兴趣,当我应该使用列表时,所以我使用过滤器和列表推导进行了一些测试。
Set src = ThisWorkbook.VBProject.VBComponents("Module2").CodeModule
Set dest = ActiveWorkbook.VBProject.VBComponents("Sheet2") _
.CodeModule
dest.DeleteLines 1, dest.CountOfLines
dest.InsertLines 1, src.Lines(1, src.CountOfLines)
然后我尝试了范围(100):
>>> 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
为什么从生成器对象创建列表所需的时间比创建列表要长得多?如果我需要不止一次访问该列表,我会更好地使用列表理解而不是从生成器对象创建列表吗?
答案 0 :(得分:3)
问题
有两个不同的问题答案 1 :(得分:-1)
我将首先回答您的上一个问题,是的,您应该使用全面的列表,而不是list
+ filter
组合,因为它更加pythonic并且当您展示它时,效率更高。< / p>
至于为什么效率更高,你在lambda
代码中的函数调用开销(filter
)在理解列表中没有。
这是另一个向您展示的时间测试:
# First the sample with list & filter, for comparison base
>>> timeit.timeit('list(filter(lambda x: x%10, range(10)))')
10.984653161001916
# Then the quickest comprehension list
>>> timeit.timeit('[i for i in range(10) if i%10]')
6.125996000002488
# And an hybrid, comprehension list using a call to previously defined lambda
>>> timeit.timeit('[i for i in range(10) if l(i)]', setup="l=lambda x: x%10")
9.257114547002857
如您所见,大部分差异来自函数调用开销。
最后1.7个无法解释的秒可能是由于filter
弹出到list
,而理解列表将值直接构建到列表中