我正在浏览Python3.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是list comprehension在内部所做的(不确定),所以为什么清单1在解释器中以c速度执行&清单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中发生。
字节码是不同的,第一个应该更快。

10-07 22:23