list[:] 的浅拷贝

根据这个官方文档:


list[:]

通过浅拷贝创建一个新列表。我进行了以下实验:


>>> squares = [1, 4, 9, 16, 25]

>>> new_squares = square[:]

>>> squares is new_squares

False

>>> squares[0] is new_squares[0]

True

>>> id(squares)

4468706952

>>> id(new_squares)

4468425032

>>> id(squares[0])

4466081856

>>> id(new_squares[0])

4466081856

这里的一切看起来都不错!new_square 和 square 是不同的对象(这里列出),但由于浅拷贝,它们共享相同的内容。但是,以下结果让我感到困惑:


>>> new_squares[0] = 0

>>> new_squares

[0, 4, 9, 16, 25]

>>> squares

[1, 4, 9, 16, 25]

我更新了 new_square[0] 但 square 不受影响。我检查了他们的身份证:


>>> id(new_squares[0])

4466081824

>>> id(squares[0])

4466081856

您会发现 squares[0] 的 id 没有变化,但 new_squares[0] 的 id 发生了变化。这和我之前理解的浅拷贝有很大的不同。


谁能解释一下?谢谢!


呼如林
浏览 245回答 2
2回答

qq_笑_17

您有一个表示其他对象容器的列表对象。当您执行浅拷贝时,您会创建一个新的列表对象(如您所见),其中包含对原始列表所包含的相同对象的引用。new_squares[0] = 0是一个任务。你说的是“在列表的第 0 个索引处设置一个新对象”。好吧,列表现在是单独的对象,并且您正在完全替换保存在副本索引处的对象。第 0 个索引处的对象是否是可变的也没关系,因为您只是替换列表对象持有的引用。如果列表包含一个可变对象,并且您要修改该对象而不完全更改存储在该索引中的对象,那么您将看到两个列表之间的更改。不是因为列表以任何方式链接,而是因为它们包含对您现在已更改的可变对象的引用。这可以在下面进行说明,我可以分别对浅复制列表进行修改,并且还可以导致可变对象在两个列表之间发生更改,即使该可变对象现在位于两者之间的不同索引处。# MAKING A CHANGE TO THE LISTa = [1, {'c': 'd'}, 3, 4]b = a[:]b.insert(0, 0)print(a)print(b)print()# MODIFYING A MUTABLE OBJECT INSIDE THE LISTa[1]['c'] = 'something_else'print(a)print(b)

一只斗牛犬

列表是可变的,整数是不可变的当你这样做时:squares = [1, 4, 9, 16, 25]new_squares = square[:]squares 和 new_squares 有不同的 id如果你这样做:[id(squares[i]) for i in range(len(squares))][id(new_squares[i]) for i in range(len(new_squares))]您将看到每个整数的相同 id。如果你用另一个值修改一个整数,你将拥有这个整数的新 id
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python