为了账号安全,请及时绑定邮箱和手机立即绑定

list[:] 的浅拷贝

list[:] 的浅拷贝

呼如林 2022-01-11 16:45:30
根据这个官方文档:list[:]通过浅拷贝创建一个新列表。我进行了以下实验:>>> squares = [1, 4, 9, 16, 25]>>> new_squares = square[:]>>> squares is new_squaresFalse>>> 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 发生了变化。这和我之前理解的浅拷贝有很大的不同。谁能解释一下?谢谢!
查看完整描述

2 回答

?
qq_笑_17

TA贡献1818条经验 获得超7个赞

您有一个表示其他对象容器的列表对象。当您执行浅拷贝时,您会创建一个新的列表对象(如您所见),其中包含对原始列表所包含的相同对象的引用。


new_squares[0] = 0是一个任务。你说的是“在列表的第 0 个索引处设置一个新对象”。好吧,列表现在是单独的对象,并且您正在完全替换保存在副本索引处的对象。第 0 个索引处的对象是否是可变的也没关系,因为您只是替换列表对象持有的引用。


如果列表包含一个可变对象,并且您要修改该对象而不完全更改存储在该索引中的对象,那么您将看到两个列表之间的更改。不是因为列表以任何方式链接,而是因为它们包含对您现在已更改的可变对象的引用。


这可以在下面进行说明,我可以分别对浅复制列表进行修改,并且还可以导致可变对象在两个列表之间发生更改,即使该可变对象现在位于两者之间的不同索引处。


# MAKING A CHANGE TO THE LIST

a = [1, {'c': 'd'}, 3, 4]

b = a[:]

b.insert(0, 0)


print(a)

print(b)

print()


# MODIFYING A MUTABLE OBJECT INSIDE THE LIST

a[1]['c'] = 'something_else'


print(a)

print(b)


查看完整回答
反对 回复 2022-01-11
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

列表是可变的,整数是不可变的


当你这样做时:


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


查看完整回答
反对 回复 2022-01-11
  • 2 回答
  • 0 关注
  • 244 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号