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

Yud*_*udi 5 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])
Run Code Online (Sandbox Code Playgroud)

如果我按如下方式使用增强分配,

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])
Run Code Online (Sandbox Code Playgroud)

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

zon*_*ndo 6

那里使用了两种方法:__add____iadd__l + [5, 6]是 的快捷方式l.__add__([5, 6])l__add__方法返回与其他内容相加的结果。因此,l = l + [5, 6]重新分配l给添加l[5, 6]。它不会影响,m因为您没有更改对象,而是重新定义名称。 l += [5, 6]是 的快捷方式l.__iadd__([5, 6])。在这种情况下,__iadd__更改列表。既然m指的是同一个对象,m也受到影响。

编辑:如果__iadd__没有实现,例如像tupleand这样的不可变类型str,那么 Python 会使用__add__。例如,x += y将转换为x = x + y. 此外,x + y如果x没有实现__add__,则y.__radd__(x),如果可用,将被使用。因此x += y 可能实际上是x = y.__radd__(x)在后台。


kar*_*ikr 5

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

在第一种情况下:

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

请注意,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
>>> 
Run Code Online (Sandbox Code Playgroud)

l += [5,6]对内存中同一个对象的引用。因此结果。所以,基本上+=相当于就地添加..更多关于这个可以在这里阅读