Python列表理解很昂贵 [英] Python list comprehension expensive
问题描述
我正在尝试查找列表理解的效率,但是它看起来比普通的函数操作更昂贵.有人可以解释吗?
Im trying to find the effeciency of list comprehension but it look like its more expensive than a normal function operation. Can someone explain?
def squares(values):
lst = []
for x in range(values):
lst.append(x*x)
return lst
def main():
t = timeit.Timer(stmt="lst = [x*x for x in range(10)]")
print t.timeit()
t = timeit.Timer(stmt="squares",setup="from __main__ import squares")
print t.timeit()
lst = [x*x for x in range(10)]
print lst
print squares(10)
----Output:---
2.4147507644
0.0284455255965
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
对于相同的输出,与列表理解相比,普通函数的计算时间要短得多.
For the same output, the normal function calculates in very less time compared to the list comprehension.
我认为列表理解更有效.
I thought the list comprehension is more effecient.
推荐答案
您永远不会调用您的squares
函数,因此它什么也没做.
You are never calling your squares
function, so it is not doing anything.
列表理解 实际上更快:
>>> import timeit
>>> def squares(values):
... lst = []
... for x in range(values):
... lst.append(x*x)
... return lst
...
>>> def squares_comp(values):
... return [x*x for x in range(values)]
...
>>> timeit.timeit('f(10)', 'from __main__ import squares as f')
3.9415171146392822
>>> timeit.timeit('f(10)', 'from __main__ import squares_comp as f')
2.3243820667266846
如果使用dis
模块查看每个功能的字节码,则可以了解原因:
If you use the dis
module to look at the bytecode for each function, you can see why:
>>> import dis
>>> dis.dis(squares)
2 0 BUILD_LIST 0
3 STORE_FAST 1 (lst)
3 6 SETUP_LOOP 37 (to 46)
9 LOAD_GLOBAL 0 (range)
12 LOAD_FAST 0 (values)
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 23 (to 45)
22 STORE_FAST 2 (x)
4 25 LOAD_FAST 1 (lst)
28 LOAD_ATTR 1 (append)
31 LOAD_FAST 2 (x)
34 LOAD_FAST 2 (x)
37 BINARY_MULTIPLY
38 CALL_FUNCTION 1
41 POP_TOP
42 JUMP_ABSOLUTE 19
>> 45 POP_BLOCK
5 >> 46 LOAD_FAST 1 (lst)
49 RETURN_VALUE
>>> dis.dis(squares_comp)
2 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (range)
6 LOAD_FAST 0 (values)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 16 (to 32)
16 STORE_FAST 1 (x)
19 LOAD_FAST 1 (x)
22 LOAD_FAST 1 (x)
25 BINARY_MULTIPLY
26 LIST_APPEND 2
29 JUMP_ABSOLUTE 13
>> 32 RETURN_VALUE
squares
函数在每次迭代中查找列表的.append()
方法,并对其进行调用. .append()
函数必须在每次调用时将列表增加一个元素.
The squares
function looks up the .append()
method of the list in each iteration, and calls it. The .append()
function has to grow the list by one element each time it is called.
另一方面,列表理解不必完成这项工作.取而代之的是,python使用LIST_APPEND
字节码,该字节码使用C API将新元素添加到列表中,而无需执行查找和对该函数的python调用.
The list comprehension on the other hand doesn't have to do that work. Instead, python uses the LIST_APPEND
bytecode, which uses the C API to append a new element to the list, without having to do the lookup and a python call to the function.
这篇关于Python列表理解很昂贵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!