python - List Comprehension 在 Python 中是如何工作的?

标签 python list-comprehension

<分区>

我正在浏览 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中。

字节码不同,第一种应该更快。

关于python - List Comprehension 在 Python 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38941643/

相关文章:

python - 通过循环创建二叉树

python - 在 Python 3 中替换字符串中的 unicode 字符

python - 如何将列表转换为 Flask 模板的类对象

python - 尝试将 csv 文件转换为更干净的 csv! python 和 Stack 新手

python - 通过正则表达式修改字符串列表

python使用列表理解对dict的多级列表进行切片

python - 如何多次迭代一个文件?

Erlang列表理解

python - 我如何通过嵌套列表理解来实现这一点?

python - 无法在 Python 3 的列表理解中使用 locals() 吗?