python - python 列表推导式是否会转换为纯 C 语言?

标签 python list-comprehension

我多次被告知 Python 列表推导式比嵌套的 forif 更好,仅仅是因为它们被转换为纯 C 并编译。但是,我找不到任何文档来支持这一点;这是真的吗?

例如;下面的代码实际上确实导致了 1/3 的性能增益(在我的机器上):

import time

start = time.time()
a = []
for i in range(0, 100000000):
  a.append(i)

end = time.time()

print("Time it took: " + str((end - start)))

start = time.time()
b = [i for i in range(0, 100000000)]
end = time.time()

print("Time it took: " + str((end - start)))

CPython 结果:

Time it took: 12.077988863
Time it took: 8.65817594528

PyPy 结果:

Time it took: 4.9356508255
Time it took: 0.686870098114

最佳答案

这是特定于实现的,但在 CPython 中,它不会编译为 C,而是编译为所谓的“字节码”。

我们可以使用用于反汇编字节码的 dis 模块来检查它。

>>> import dis
>>> def foo():
...     return [i//2 for i in range(20)]
... 
>>> dis.dis(foo)
  2           0 BUILD_LIST               0
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (20)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                16 (to 32)
             16 STORE_FAST               0 (i)
             19 LOAD_FAST                0 (i)
             22 LOAD_CONST               2 (2)
             25 BINARY_FLOOR_DIVIDE 
             26 LIST_APPEND              2
             29 JUMP_ABSOLUTE           13
        >>   32 RETURN_VALUE        

在其他实现中,它可以编译为 C。我对这些其他实现不太熟悉,因此我将保留对它们的评论。

关于您的声明:

list comprehensions are better than nested for, if ...

在某些情况下,使用 for 列表和条件更有意义。最好的方法是使用您最易读的内容,然后在需要提高性能时分析您的代码。有时,您实际上并不需要由列表理解或生成器表达式创建的列表或生成器,在这种情况下,使用带有 if 条件的 for 循环通常性能更高。

推测:

但是,在您给出的示例中,您特别打算创建一个列表。在循环中附加到列表是执行此操作的规范方法,但正如您通过检查运行时知道的那样,列表理解速度更快。它更快的原因是 Python 的设计者知道列表推导将填充列表,因此有机会对其进行优化。在 for 循环中,优化它会更加困难,因为您必须能够在那里处理更复杂的语句。

我想您在 PyPy 中的巨大改进是由于对 i for i 部分进行了优化,并且可能只是在迭代器上调用 list

关于python - python 列表推导式是否会转换为纯 C 语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24482810/

相关文章:

python - lmdb.BadRslotError : mdb_txn_begin: MDB_BAD_RSLOT: Invalid reuse of reader locktable slot?

python - 如何在 Keras 的每个时期保存训练历史?

python - 检测 POS 标签模式以及指定的单词

Python Pandas 数据框 : filter columns using a list?

python - Flask - 函数映射正在覆盖现有端点函数

python - 计算列表中所有大于或等于 50 的数字的平均值?

python - 列表理解和 "not in"关键字

Python:如何为嵌套列表返回具有特定格式的字符串

Python Pandas - 使用列表理解来连接数据框

python - Python列表,列表项中间有空格