为什么列表理解比附加到列表要快得多?

编程入门 行业动态 更新时间:2024-10-27 04:28:51
本文介绍了为什么列表理解比附加到列表要快得多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想知道为什么列表理解比附加到列表要快得多.我认为差异只是表现力,但事实并非如此.

>>>导入时间>>>timeit.timeit(stmt=''' = []对于我在范围内(10000):t.append(i)''', number=10000)9.467898777974142>>>timeit.timeit(stmt='t= [i for i in range(10000)]', number=10000)4.1138417314859

列表理解速度提高了 50%.为什么?

解决方案

列表推导 基本上只是一个语法糖";对于常规 for 循环.在这种情况下,它表现更好的原因是它不需要加载列表的 append 属性并在每次迭代时将其作为函数调用.换句话说,一般来说,列表推导式执行得更快,因为暂停和恢复函数的框架,或其他情况下的多个函数,比按需创建列表慢.

考虑以下示例:

在 [1]: def f1():...: l = []...:对于范围内的我(5):...: l.append(i)...:...:...: def f2():...: [i for i in range(5)]...:在[3]中:导入dis在 [4] 中:dis.dis(f1)2 0 BUILD_LIST 02 STORE_FAST 0 (升)3 4 LOAD_GLOBAL 0(范围)6 LOAD_CONST 1 (5)8 CALL_FUNCTION 110 GET_ITER>>12 FOR_ITER 14(到 28)14 STORE_FAST 1 (i)4 16 LOAD_FAST 0 (升)18 LOAD_METHOD 1(附加)20 LOAD_FAST 1 (i)22 CALL_METHOD 124 POP_TOP26 JUMP_ABSOLUTE 12>>28 LOAD_CONST 0 (无)30 RETURN_VALUE在 [5]:在 [5] 中:dis.dis(f2)8 0 LOAD_CONST 1(<代码对象在0x7f397abc0d40,文件)2 LOAD_CONST 2 ('f2..')4 MAKE_FUNCTION 06 LOAD_GLOBAL 0(范围)8 LOAD_CONST 3 (5)10 CALL_FUNCTION 112 GET_ITER14 CALL_FUNCTION 116 POP_TOP18 LOAD_CONST 0 (无)20 RETURN_VALUE<代码对象<listcomp>的反汇编在 0x7f397abc0d40,文件<ipython-input-1-45c11e415ee9>",第 8 行>:8 0 BUILD_LIST 02 LOAD_FAST 0 (.0)>>4 FOR_ITER 8(到 14)6 STORE_FAST 1 (i)8 LOAD_FAST 1 (i)10 LIST_APPEND 212 JUMP_ABSOLUTE 4>>14 RETURN_VALUE在 [6] 中:

您可以看到,在第一个函数的偏移量 18 处,我们有一个 append 属性,而在使用列表推导式的第二个函数中没有这样的东西.所有这些额外的字节码都会使追加方法变慢,因为在这种情况下,您将在每次迭代中加载 append 属性,最终它将使代码仅使用列表推导式,其运行速度大约是第二个函数的两倍.

I was wondering why list comprehension is so much faster than appending to a list. I thought the difference is just expressive, but it's not.

>>> import timeit >>> timeit.timeit(stmt=''' t = [] for i in range(10000): t.append(i)''', number=10000) 9.467898777974142 >>> timeit.timeit(stmt='t= [i for i in range(10000)]', number=10000) 4.1138417314859

The list comprehension is 50% faster. Why?

解决方案

List comprehension is basically just a "syntactic sugar" for the regular for loop. In this case the reason that it performs better is because it doesn't need to load the append attribute of the list and call it as a function at each iteration. In other words and in general, list comprehensions perform faster because suspending and resuming a function's frame, or multiple functions in other cases, is slower than creating a list on demand.

Consider the following examples :

In [1]: def f1(): ...: l = [] ...: for i in range(5): ...: l.append(i) ...: ...: ...: def f2(): ...: [i for i in range(5)] ...: In [3]: import dis In [4]: dis.dis(f1) 2 0 BUILD_LIST 0 2 STORE_FAST 0 (l) 3 4 LOAD_GLOBAL 0 (range) 6 LOAD_CONST 1 (5) 8 CALL_FUNCTION 1 10 GET_ITER >> 12 FOR_ITER 14 (to 28) 14 STORE_FAST 1 (i) 4 16 LOAD_FAST 0 (l) 18 LOAD_METHOD 1 (append) 20 LOAD_FAST 1 (i) 22 CALL_METHOD 1 24 POP_TOP 26 JUMP_ABSOLUTE 12 >> 28 LOAD_CONST 0 (None) 30 RETURN_VALUE In [5]: In [5]: dis.dis(f2) 8 0 LOAD_CONST 1 (<code object <listcomp> at 0x7f397abc0d40, file "<ipython-input-1-45c11e415ee9>", line 8>) 2 LOAD_CONST 2 ('f2.<locals>.<listcomp>') 4 MAKE_FUNCTION 0 6 LOAD_GLOBAL 0 (range) 8 LOAD_CONST 3 (5) 10 CALL_FUNCTION 1 12 GET_ITER 14 CALL_FUNCTION 1 16 POP_TOP 18 LOAD_CONST 0 (None) 20 RETURN_VALUE Disassembly of <code object <listcomp> at 0x7f397abc0d40, file "<ipython-input-1-45c11e415ee9>", line 8>: 8 0 BUILD_LIST 0 2 LOAD_FAST 0 (.0) >> 4 FOR_ITER 8 (to 14) 6 STORE_FAST 1 (i) 8 LOAD_FAST 1 (i) 10 LIST_APPEND 2 12 JUMP_ABSOLUTE 4 >> 14 RETURN_VALUE In [6]:

You can see that on offset 18 in the first function we have an append attribute while there's no such thing in second function using list comprehension. All those extra bytecodes will make the appending approach slower and since in this case you'll have loading of the append attribute in each iteration, in the end it will make the code to take approximately twice as slower as the second function using only list comprehension.

更多推荐

为什么列表理解比附加到列表要快得多?

本文发布于:2023-11-05 03:57:16,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1559826.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:列表   得多   要快

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!