我制作了这行代码:
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()函数是否未传递引用,而是添加深层副本?
答案 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 values的Ned Batchelder。
答案 1 :(得分:0)
不,你误解了引用和副本。事实上,与你说的相反是正确的; append
会附加对blist
中当前内容的引用。但是blist的内容,而不是名称本身,是参考;因此,如果您稍后更改分配给blist的内容,则同样在alist中的引用不会受到影响。
但是,如果突变内容,那将会受到影响:
alist.append(blist)
blist[0] = 7
print(alist) # => [8, 6, 9, 2, 4, [7, 5, 6]]