用嵌套列表验证修改原始对象的内层元素时,浅拷贝会不会跟着变、深拷贝会不会独立,并用id()确认背后的对象关系。
copy.copy是浅拷贝,copy.deepcopy是深拷贝,差别只在"嵌套"结构上才会显现。
代码original = [[1, 2, 3], [4, 5, 6]] shallow = copy.copy(original) deep = copy.deepcopy(original) original[0].append(999) -- 修改original内层的子列表
三个变量,同一次修改,看到两种不同的反应。
结果修改original[0]后: original = [[1, 2, 3, 999], [4, 5, 6]] shallow = [[1, 2, 3, 999], [4, 5, 6]] ← 也跟着变了! deep = [[1, 2, 3], [4, 5, 6]] ← 完全没受影响
结果一目了然:只修改了 original,shallow 也跟着变了,deep 纹丝不动。
现象背后,的对象关系是什么样的。
结果original is shallow: False(外层是不同对象) original[1] is shallow[1]: True(内层元素是同一个对象!) original[1] is deep[1]: False(deepcopy连内层也复制了新对象)
的对象关系是:copy.copy() 只创建了一个新的外层列表容器,但容器里装的元素(这里是两个内层子列表)还是原来那两个对象,只是被两个不同的外层列表同时引用着——改动内层子列表,两边看到的自然是同一份数据。copy.deepcopy() 则是递归地把外层、内层全部都创建了新对象,原始对象和深拷贝之间没有任何共享的可变对象。
每一步都是本文上面用Python 3.14跑出来的原始结果。
copy.copy / copy.deepcopy:对比嵌套结构下的拷贝行为is / id():验证内层元素是否共享同一个对象