Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.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
Python 添加和扩展两个列表在时间上存在奇怪的差异_Python_Python 3.x_Performance - Fatal编程技术网

Python 添加和扩展两个列表在时间上存在奇怪的差异

Python 添加和扩展两个列表在时间上存在奇怪的差异,python,python-3.x,performance,Python,Python 3.x,Performance,如果我使用两个列表,我可以使用+运算符或.extend()方法将它们连接起来。两者都做同样的事情 但是如果我做list1=list1+list2,它需要接近0.048ms。相反,如果我执行list1.extend(list2),则需要 此操作创建新列表而不影响任何列表: list1=list1+list2 此操作不会创建新操作并更改第一个操作: list1.extend(list2) 将第二个与: list1 += list2 他们不是在做同样的事情。考虑以下设置: list1 = [1,

如果我使用两个列表,我可以使用+运算符或.extend()方法将它们连接起来。两者都做同样的事情

但是如果我做
list1=list1+list2
,它需要接近0.048ms。相反,如果我执行
list1.extend(list2)
,则需要

此操作创建新列表而不影响任何列表:

list1=list1+list2
此操作不会创建新操作并更改第一个操作:

list1.extend(list2)
将第二个与:

list1 += list2

他们不是在做同样的事情。考虑以下设置:

list1 = [1, 2, 3]
list2 = [4, 5]
list3 = list1
如果然后运行
list1=list1+list2
list1.extend(list2)
,则在
list3

list1 = list1 + list2
print(list3)  # [1, 2, 3]

之所以会出现这种情况,是因为运算符
+
为列表1创建了新对象,但
extend
就地修改列表,而列表3指向同一个对象。

是否要同时比较两个代码段
dis
模块是您的朋友

In [3]: dis.dis("l1=[1, 2, 3];l2=[4, 5, 6];l1=l1+l2")                                                                                                                                                       
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 LOAD_CONST               2 (3)
              6 BUILD_LIST               3
              8 STORE_NAME               0 (l1)
             10 LOAD_CONST               3 (4)
             12 LOAD_CONST               4 (5)
             14 LOAD_CONST               5 (6)
             16 BUILD_LIST               3
             18 STORE_NAME               1 (l2)
             20 LOAD_NAME                0 (l1)
             22 LOAD_NAME                1 (l2)
             24 BINARY_ADD
             26 STORE_NAME               0 (l1)
             28 LOAD_CONST               6 (None)
             30 RETURN_VALUE

In [4]: dis.dis("l1=[1, 2, 3];l2=[4, 5, 6];l1.extend(l2)")                                                                                                                                                  
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (2)
              4 LOAD_CONST               2 (3)
              6 BUILD_LIST               3
              8 STORE_NAME               0 (l1)
             10 LOAD_CONST               3 (4)
             12 LOAD_CONST               4 (5)
             14 LOAD_CONST               5 (6)
             16 BUILD_LIST               3
             18 STORE_NAME               1 (l2)
             20 LOAD_NAME                0 (l1)
             22 LOAD_METHOD              2 (extend)
             24 LOAD_NAME                1 (l2)
             26 CALL_METHOD              1
             28 POP_TOP
             30 LOAD_CONST               6 (None)
             32 RETURN_VALUE

In [5]:  
正如你所看到的,这里的区别在于第一个代码的以下部分:

         24 BINARY_ADD
         26 STORE_NAME 
第二节的内容如下:

         22 LOAD_METHOD              2 (extend)
         26 CALL_METHOD              1
         28 POP_TOP

第二个代码中的所有三条指令的时间大致与第一个代码中的
BINARY\u ADD
指令相同。事实上,他们也在做类似的工作,将项目从一个列表添加到另一个列表。但是第一个代码中额外的
STORE\u NAME
会导致速度变慢,因为装入新对象并将其存储在内存中需要时间。

这很有意义!我试了第三个,速度更快,非常感谢。(我必须等近3分钟才能选择您的答案)。只是想澄清一下,+=比extend()快的原因是另一个事实,extend是一个方法,所以必须调用它?我认为+=和extend的speedOn差不多,大约580k次调用+=比extend()少50毫秒。这可能取决于我的电脑。
list1+list2
分配一个新列表,然后将其分配给名称
list1
list1.extend(list2)
就地修改
list1
,导致分配减少。
         22 LOAD_METHOD              2 (extend)
         26 CALL_METHOD              1
         28 POP_TOP