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