我正在浏览 Python 3.X 的文档,我对 List Comprehension 的执行速度及其具体工作方式存有疑问。
举个例子:
list 1
...
L = range(0,10)
L = [x ** 2 for x in L]
...
据我所知,这会返回一个新的列表,它等价于写下来:
list 2
...
res = []
for x in L:
res.append(x ** 2)
...
如果我是正确的话,主要区别在于执行速度。 list 1 应该在解释器中以 C 语言的速度执行,而 list 2 则不是。
但 list 2 是列表理解在内部执行的操作(不确定),所以为什么 list 1 在解释器内部以 C 速度执行而 list 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中。
字节码不同,第一种应该更快。