Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.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 2.7_Python 3.x - Fatal编程技术网

Python列表:为什么在连接操作后创建新的列表对象?

Python列表:为什么在连接操作后创建新的列表对象?,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我正在浏览学习Python 5E书中关于列表的主题。 我注意到,若我们在列表上进行连接,它会创建新的对象。扩展方法不创建新对象,即就地更改。 在串联的情况下会发生什么 比如说 l = [1,2,3,4] m = l l = l + [5,6] print l,m #output ([1,2,3,4,5,6], [1,2,3,4]) 如果我使用如下的增广赋值 l = [1,2,3,4] m = l l += [5,6] print l,m #output ([1,2,3,4,5,6], [1

我正在浏览学习Python 5E书中关于列表的主题。 我注意到,若我们在列表上进行连接,它会创建新的对象。扩展方法不创建新对象,即就地更改。 在串联的情况下会发生什么

比如说

l = [1,2,3,4]
m = l
l = l + [5,6]
print l,m

#output
([1,2,3,4,5,6], [1,2,3,4])
如果我使用如下的增广赋值

l = [1,2,3,4]
m = l
l += [5,6]
print l,m

#output
([1,2,3,4,5,6], [1,2,3,4,5,6])

在这两种操作的情况下,后台会发生什么情况?

在后台使用两种方法:
\uuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuidd
l+[5,6]
l.\uu添加([5,6])
的快捷方式
l
\uuuuu add\uuuu
方法返回与其他内容相加的结果。因此,
l=l+[5,6]
l
重新分配给添加的
l
[5,6]
。它不会影响
m
,因为您没有更改对象,而是重新定义了名称
l+=[5,6]
l.\uu iadd\uuu([5,6])
的快捷方式。在这种情况下,
\uuuu iadd\uuu
会更改列表。由于
m
引用相同的对象,因此
m
也会受到影响


Edit:如果未实现
\uuuu iadd\uuuuuu
,例如使用不可变类型,如
tuple
str
,那么Python将使用
\uuuu add\uuuuu
。例如,
x+=y
将转换为
x=x+y
。此外,在
x+y
中,如果
x
未实现
\uuuu添加
,则将使用
y.\uuu radd\uuuuu(x)
(如果可用)。因此
x+=y
实际上可能是
x=y.\uuu radd\uuuu(x)
背景。

通过检查内存中引用的对象,您可以更好地理解这一点。让我们使用

在第一种情况下:

>>> l = [1,2,3,4]
>>> id(l)
4497052232
>>> m = l
>>> id(m)
4497052232
>>> l = l + [5,6]
>>> id(l)
4497052448
>>> print l, id(l), m, id(m)
[1, 2, 3, 4, 5, 6] 4497052448 [1, 2, 3, 4] 4497052232
>>> 
请注意,
l=l+[5,6]
在内存中创建了一个新对象,并且
l
引用了该对象

在第二种情况下:

>>> l = [1,2,3,4]
>>> id(l)
4497052520
>>> m = l
>>> id(m)
4497052520
>>> l += [5,6]
>>> id(l)
4497052520
>>> print l, id(l), m, id(m)
[1, 2, 3, 4, 5, 6] 4497052520 [1, 2, 3, 4, 5, 6] 4497052520
>>> 
l+=[5,6]
引用内存中的同一对象。结果就是这样。
因此,基本上,
+=
相当于inplace add

注意这里有一个重要的警告:不可变类型不实现
\uuuuuidd\uuuuu
,对于任何具有
\uuuuuuadd\uuuuu
但不具有
\uuuuidd\uuuuuu
的对象,Python都会使用
\uuuuuuadd\uuuuu
来执行操作。因此,对于
tuple
s,当你做
a=(1,2)
b=a
a+=(3,4)
,由于
tuple
是不可变的,实际上就好像最后一条语句是
a=a+(3,4)
,因为
a
被一个全新的
tuple
所取代,而
b
继续引用原始
(1,2)
元组。我喜欢
\uuuu radd\uuuu
上的添加。