.append()函数如何在python中工作

时间:2015-10-30 15:43:05

标签: python reference

我制作了这行代码:

alist = [8,6,9,2,4]

blist = [4,5,6]

alist.append(blist)

blist = [7,8,9]

print(alist)

我认为这会打印 [8,6,9,2,4,[7,8,9]] ,但它打印出来 [8,6,9,2,4,[4,5,6]] 。 .append()函数是否未传递引用,而是添加深层副本?

2 个答案:

答案 0 :(得分:1)

blist = [7,8,9]不会改变blist引用的对象。相反,名称blist现在引用一个新对象。旧对象仍然作为alist的最后一个元素存在。

>>> alist = [8,6,9,2,4]
>>> blist = [4,5,6]
>>> alist.append(blist)
>>> id(blist)
37490560
>>> id(alist[-1]) # should be the same as blist
37490560
>>> blist = [7,8,9] # blist now refers to a new object
>>> id(blist) # its a new object so the id is different
71420104
>>> id(alist[-1]) 
37490560

您的心理模型似乎是这样的:alist[-1]指的是blist,它引用了对象[4,5,6]。如果该模型是正确的,则blist = [7,8,9]会使alist[-1]引用blist的新值。

然而,这种模式是错误的。 alist.append(blist)并未使alist的最后一个元素引用blist。它使最后一个元素直接引用blist在附加到alist时引用的对象。名称blist不是alist[-1][4,5,6]之间关系链中的链接。这就是为什么分配到blist不会影响alist的内容。

有关此内容的详细讨论,请参阅Facts and myths about Python names and valuesNed Batchelder

答案 1 :(得分:0)

不,你误解了引用和副本。事实上,与你说的相反是正确的; append会附加对blist中当前内容的引用。但是blist的内容,而不是名称本身,是参考;因此,如果您稍后更改分配给blist的内容,则同样在alist中的引用不会受到影响。

但是,如果突变内容,那将会受到影响:

alist.append(blist)
blist[0] = 7
print(alist)   # => [8, 6, 9, 2, 4, [7, 5, 6]]