Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是什么让Pythons附加列表方法如此之快?_Python_Performance - Fatal编程技术网

是什么让Pythons附加列表方法如此之快?

是什么让Pythons附加列表方法如此之快?,python,performance,Python,Performance,我正在比较python中向列表追加项的不同方式。我在我的计算机上进行了测试,结果当然会在其他计算机上有所不同 选项1:5.80秒仅50000项 a = [] for i in range(50000): a = a + [i] 选项2:2.27秒10000000项 a = [] for i in range(10000000): a += [i] a = [] for i in range(10000000): a.append(i) 选项3:1.53秒100000

我正在比较python中向列表追加项的不同方式。我在我的计算机上进行了测试,结果当然会在其他计算机上有所不同

选项1:5.80秒仅50000项

a = []
for i in range(50000):
    a = a + [i]
选项2:2.27秒10000000项

a = []
for i in range(10000000):
    a += [i]
a = []
for i in range(10000000):
    a.append(i)
选项3:1.53秒10000000项

a = []
for i in range(10000000):
    a += [i]
a = []
for i in range(10000000):
    a.append(i)
不足为奇,选项1的速度很慢,因为它每次都会创建列表的新副本

选项2使用增广赋值运算符要快得多。它修改了原来的列表

但选项3的速度仍然要快得多。我希望使用append()方法和增广赋值运算符得到相同的结果

为什么append()方法仍然比+=运算符快得多?

附言: 我的python版本:

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32
第二种方法仍然需要创建临时列表
[i]
。查看拆解后的代码:

>>> import dis
>>> def func_2(a, i):
...     a += [i]
... 
>>> def func_3(a, i):
...     a.append(i)
... 
>>> dis.dis(func_2)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (i)
              6 BUILD_LIST               1
              9 INPLACE_ADD         
             10 STORE_FAST               0 (a)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE        
>>> dis.dis(func_3)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_ATTR                0 (append)
              6 LOAD_FAST                1 (i)
              9 CALL_FUNCTION            1
             12 POP_TOP             
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE        
>>> 

第二种方法需要
6个构建列表
,但第三种方法不需要。可能还有其他原因,但这应该是方法3速度更快的主要原因。

我猜它们在增长基础列表时分配的额外空间量不同。您正在创建一个新列表并扩展而不是简单的追加,因此追加速度快得多并不奇怪。对于您的编辑,您正在执行一个setitem,然后再次进行扩展,这并不奇怪。append只做了一件事,而且做得很好,从来没有一个实际的用例可以使用任何其他方法将单个元素附加到列表中。这对我来说是有意义的。正是+=运算符后面的[i]导致了创建新列表对象的开销。