Python列表理解vs For

Python列表理解vs For,python,Python,在Python中,列表理解为什么比for循环的性能更好 列表理解: for循环: 是否还有其他示例(不是循环),其中一个Python结构的性能比另一个Python结构差 for语句是最常用的。它在元素上循环 一个序列,将每个序列分配给循环变量。如果你的身体 循环很简单,for循环本身的解释器开销可以 大量的开销。这就是地图功能的所在 这很方便。您可以将map视为迁移到C代码中的一种方法 简单的for循环会产生开销,而列表理解可以避免这些开销。本质上,列表理解和for循环做的事情非常相似,列表理解

在Python中,列表理解为什么比for循环的性能更好

列表理解:

for循环:

是否还有其他示例(不是循环),其中一个Python结构的性能比另一个Python结构差

for语句是最常用的。它在元素上循环 一个序列,将每个序列分配给循环变量。如果你的身体 循环很简单,for循环本身的解释器开销可以 大量的开销。这就是地图功能的所在 这很方便。您可以将map视为迁移到C代码中的一种方法


简单的for循环会产生开销,而列表理解可以避免这些开销。

本质上,列表理解和for循环做的事情非常相似,列表理解可以消除一些开销,让它看起来更漂亮。 要理解为什么这样更快,您应该查看并引用问题的相关部分:

列表理解在这里性能更好,因为您不需要加载 列表的append属性(循环程序,字节码28)和 将其作为函数调用(循环程序,字节码38)。相反,在 理解时,会为 快速附加到结果列表(理解程序,字节码33)

在更快的循环程序中,可以避免追加的开销 通过将属性从循环中提升出来并放置结果来查找属性 在fastlocal(字节码9-12)中,循环速度更快;但是, 理解使用专门的列表\附加字节码,而不是 导致函数调用的开销,因此它仍然占优势


该链接还详细介绍了与lc相关的一些可能的陷阱,我建议您进行一次检查。

假设我们在这里讨论的是CPython,您可以使用该模块来比较生成的字节码:

>> def one():
       return [a for a in items if a > 10]

>> def two():
       res = []
       for a in items:
           if a > 10:
               res.append(a)

>> dis.dis(one)

  2           0 BUILD_LIST               0
              3 LOAD_GLOBAL              0 (items)
              6 GET_ITER
        >>    7 FOR_ITER                24 (to 34)
             10 STORE_FAST               0 (a)
             13 LOAD_FAST                0 (a)
             16 LOAD_CONST               1 (10)
             19 COMPARE_OP               4 (>)
             22 POP_JUMP_IF_FALSE        7
             25 LOAD_FAST                0 (a)
             28 LIST_APPEND              2
             31 JUMP_ABSOLUTE            7
        >>   34 RETURN_VALUE

>> dis.dis(two)
  2           0 BUILD_LIST               0
              3 STORE_FAST               0 (res)

  3           6 SETUP_LOOP              42 (to 51)
              9 LOAD_GLOBAL              0 (items)
             12 GET_ITER
        >>   13 FOR_ITER                34 (to 50)
             16 STORE_FAST               1 (a)

  4          19 LOAD_FAST                1 (a)
             22 LOAD_CONST               1 (10)
             25 COMPARE_OP               4 (>)
             28 POP_JUMP_IF_FALSE       13

  5          31 LOAD_FAST                0 (res)
             34 LOAD_ATTR                1 (append)
             37 LOAD_FAST                1 (a)
             40 CALL_FUNCTION            1
             43 POP_TOP
             44 JUMP_ABSOLUTE           13
             47 JUMP_ABSOLUTE           13
        >>   50 POP_BLOCK
        >>   51 LOAD_CONST               0 (None)
             54 RETURN_VALUE

因此,首先,列表理解利用了for循环未使用的专用
list\u APPEND
操作码。

是任何其他示例(非循环),当一个Python结构的性能比其他Python结构差时?-例如,有无限多的。@Lattyware?如果性能是唯一的原因,那么您不应该太担心lc vs loop。担心你的整体算法是正确的,担心你能很好地理解你写的代码。@TomCruise
filer(lambda x:x>10,items)
@drewk,我知道,但在这种情况下,性能是我的线索。另外,如果你想对代码计时,你可以在IPythonaldo中使用
%timeit
魔术函数,所以LC不必担心语句之类的事情,因为LCs中只允许表达式。这不太好。首先它是一个很长的语句,所以我必须把它分成多行。一旦出现这种情况,理解对我来说就没什么意义了:
[[1如果item_idx==row_idx else 0表示item_idx在范围内(0,3)]表示row_idx在范围内(0,3)]
,这是一个示例。链接似乎已断开:(过了很长一段时间才回来查看。链接确实断了。这是wayback machine@masterforker提供的最新url
new_items = []
for a in items:
    if a > 10: new_items.append(a)
>> def one():
       return [a for a in items if a > 10]

>> def two():
       res = []
       for a in items:
           if a > 10:
               res.append(a)

>> dis.dis(one)

  2           0 BUILD_LIST               0
              3 LOAD_GLOBAL              0 (items)
              6 GET_ITER
        >>    7 FOR_ITER                24 (to 34)
             10 STORE_FAST               0 (a)
             13 LOAD_FAST                0 (a)
             16 LOAD_CONST               1 (10)
             19 COMPARE_OP               4 (>)
             22 POP_JUMP_IF_FALSE        7
             25 LOAD_FAST                0 (a)
             28 LIST_APPEND              2
             31 JUMP_ABSOLUTE            7
        >>   34 RETURN_VALUE

>> dis.dis(two)
  2           0 BUILD_LIST               0
              3 STORE_FAST               0 (res)

  3           6 SETUP_LOOP              42 (to 51)
              9 LOAD_GLOBAL              0 (items)
             12 GET_ITER
        >>   13 FOR_ITER                34 (to 50)
             16 STORE_FAST               1 (a)

  4          19 LOAD_FAST                1 (a)
             22 LOAD_CONST               1 (10)
             25 COMPARE_OP               4 (>)
             28 POP_JUMP_IF_FALSE       13

  5          31 LOAD_FAST                0 (res)
             34 LOAD_ATTR                1 (append)
             37 LOAD_FAST                1 (a)
             40 CALL_FUNCTION            1
             43 POP_TOP
             44 JUMP_ABSOLUTE           13
             47 JUMP_ABSOLUTE           13
        >>   50 POP_BLOCK
        >>   51 LOAD_CONST               0 (None)
             54 RETURN_VALUE