我将通过Python 3.X的文档,我对列表理解的执行速度以及它的确切工作方式表示怀疑。
我们采取以下示例:
清单1
...
L = range(0,10)
L = [x ** 2 for x in L]
...
现在据我所知,这将返回一个新的列表,并且等效来写下来:
清单2
...
res = []
for x in L:
res.append(x ** 2)
...
如果我是正确的,主要区别在于执行速度。清单1应该在解释器内部以C语言速度执行,而清单2则不是。
但是清单2是列表理解在内部的作用(不确定),所以为什么清单1在解释器内部以C Speed执行。清单2不是?在处理之前,两者都被转换为字节代码,或者我错过了什么?
答案 0 :(得分:2)
答案实际上在你的问题中。
当你运行任何内置的python函数时,你运行的是用C编写并编译成机器代码的东西。
当你编写自己的版本时,必须将该代码转换为由解释器处理的CPython对象。
因此,内置的方法或函数在Python中总是比编写自己的函数更快(或占用更少的空间)。
答案 1 :(得分:2)
查看生成的实际字节码。我将这两段代码放入了名为f1和f2的函数中。
理解是这样的:
3 15 LOAD_CONST 3 (<code object <listcomp> at 0x7fbf6c1b59c0, file "<stdin>", line 3>)
18 LOAD_CONST 4 ('f1.<locals>.<listcomp>')
21 MAKE_FUNCTION 0
24 LOAD_FAST 0 (L)
27 GET_ITER
28 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
31 STORE_FAST 0 (L)
注意字节码中没有循环。循环发生在C。
现在for循环执行此操作:
4 21 SETUP_LOOP 31 (to 55)
24 LOAD_FAST 0 (L)
27 GET_ITER
>> 28 FOR_ITER 23 (to 54)
31 STORE_FAST 2 (x)
34 LOAD_FAST 1 (res)
37 LOAD_ATTR 1 (append)
40 LOAD_FAST 2 (x)
43 LOAD_CONST 3 (2)
46 BINARY_POWER
47 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
50 POP_TOP
51 JUMP_ABSOLUTE 28
>> 54 POP_BLOCK
与理解相反,循环显然在字节码中。所以循环发生在python中。
字节码不同,第一个应该更快。