繁体   English   中英

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

[英]How does List Comprehension exactly work in Python?

我将通过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在解释器和清单2中的C Speed执行呢? 在处理之前,两者都被转换为字节代码,或者我错过了什么?

答案实际上在你的问题中。

当你运行任何内置的python函数时,你运行的东西已经用C编写并编译成机器代码。

当您编写自己的版本时,必须将该代码转换为由解释器处理的CPython对象。

因此,内置方法或函数在Python中总是比编写自己的函数更快(或占用更少的空间)。

查看生成的实际字节码。 我把这两段代码放到了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中。

字节码是不同的,第一个应该更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM