Python对比List Comprehension(列表推导式)和列表的append函数的效率

时间:2022-06-01 18:22:29

测试1:是否List Comprehension(列表推导式)就比list的append快:

def ():
"""Stupid test function"""
L = []
for i in range(100):
L.append(i*2)
return L
def test2():
return [i * 2 for i in range(100)]
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))
print('------')
print(timeit.timeit("test2()", setup="from __main__ import test2"))

结果如下:

16.2206947803
------
12.4496650696

看来List Comprehension确实比在一个列表上不停append要快。

测试2:使用dis查看函数的字节码:

import dis
def list_c(nums):
return [i*2 for i in nums]
print 'return [i*2 for i in nums]'
dis.dis(list_c)
print '--------------'
print '--------------'
print '--------------'
def append_list(nums):
alist = []
for i in nums:
alist.append(i*2)
return alist
dis.dis(append_list)

结果如下:

return [i*2 for i in nums]
5 0 BUILD_LIST 0
3 LOAD_FAST 0 (nums)
6 GET_ITER
>> 7 FOR_ITER 16 (to 26)
10 STORE_FAST 1 (i)
13 LOAD_FAST 1 (i)
16 LOAD_CONST 1 (2)
19 BINARY_MULTIPLY
20 LIST_APPEND 2
23 JUMP_ABSOLUTE 7
>> 26 RETURN_VALUE
--------------
--------------
--------------
17 0 BUILD_LIST 0
3 STORE_FAST 1 (alist)
18 6 SETUP_LOOP 31 (to 40)
9 LOAD_FAST 0 (nums)
12 GET_ITER
>> 13 FOR_ITER 23 (to 39)
16 STORE_FAST 2 (i)
19 19 LOAD_FAST 1 (alist)
22 LOAD_ATTR 0 (append)
25 LOAD_FAST 2 (i)
28 LOAD_CONST 1 (2)
31 BINARY_MULTIPLY
32 CALL_FUNCTION 1
35 POP_TOP
36 JUMP_ABSOLUTE 13
>> 39 POP_BLOCK
20 >> 40 LOAD_FAST 1 (alist)
43 RETURN_VALUE

通过字节码,可以看出来,list comprehension的指令更少,不需要建立列表变量,同时,也就无需取变量,

更不需要调用list的append函数(调用函数需要维护stack信息),也就比append要快。

查看Python的官方wiki的Loop页面,也有提到map和for loop中append的问题:

newlist = []
for word in oldlist:
newlist.append(word.upper())

和:

newlist = map(str.upper, oldlist)

这里map要比for loop快,因为for loop是在解释器中执行的,而map则是编译好的C代码。

测试代码如下:

def ():
"""Stupid test function"""
oldlist = 'abcde'
newlist = []
for word in oldlist:
newlist.append(word.upper())
return newlist
def test2():
oldlist = 'abcde'
return map(str.upper, oldlist)
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))
print('------')
print(timeit.timeit("test2()", setup="from __main__ import test2"))

结果如下:

3.65194892883
------
2.49910998344