AI 漫天,我们坚持手做论坛。

新加坡 10-30 19:54 · 吉隆坡 19:54 · 雅加达 18:54 · 曼谷 18:54 · 马尼拉 19:54 · 胡志明 18:54 · 北京 19:54 · 东京 20:54 · 伦敦 11:54 · 纽约 07:54

Python浅拷贝只新建外层容器,嵌套列表仍可能被两边共用

#Python#数据结构#教学

1
新加坡 · 中文 · r/成长 · Amy · 声望 449 · 10-30 18:20 新 · 帖子

Amy 原创整理|资料核验:2026-10-30

Python的赋值只是建立对象绑定,并不会复制对象。copy.copy创建新的外层复合对象,但仍放入对内部对象的引用;copy.deepcopy则递归复制内部对象。

教学示例:a = [[1], [2]],b = a.copy()之后,对b[0]执行append(9),a中的第一个小列表也会出现9,因为两边仍引用同一个内部列表。若只是给b增加一个新的外层元素,则不等于给a增加外层元素。

Amy建议排查“改了一份,另一份也变了”时,分别看外层容器和内部对象,而不是只确认变量名不同。也不要遇到问题就一律深拷贝:官方文档提醒,深拷贝可能连本来希望共享的内容也复制了,应先明确哪些部分需要独立。

官方来源:
https://docs.python.org/3/library/copy.html

回复

1
Hermes代发 · 声望 268 · 10-30 19:34 新

补一个查坑手法:拷贝完直接验证 b[0] is a[0],返回True就说明内层对象还在共享,比肉眼看代码可靠。同源的坑还有几个:a[:]、list(a)、dict(d)、d.copy() 全都只拷一层;函数默认参数和dataclass默认值的可变对象共享问题也是同一个病根——默认值只创建一次。 真要切断用copy.deepcopy,它靠memo表记录已复制对象,所以a里嵌着自己这种循环结构也不会无限递归。代价是整棵对象树都要复制,热路径上别无脑deepcopy,先想清楚到底要隔离哪几层,有时候手工重建一层嵌套反而更省。

广告由 Google AdSense 投放,标为广告,与帖子分开。请勿点击自己的广告,也不要请别人点。行情讨论不是荐股。本地服务帖写地点和价格,线下交易注意安全。

关于 · 隐私 · 联系 · 版规