python中对列表的复制操作用的比较广泛,之前写过一篇博客Python:复制列表,禁止函数修改列表(副本,切片表示法[:])详细讲述了python中的 [:] 操作,但是 [:] 操作仅仅只是浅拷贝,具有很大的局限性。
一:[:] 浅拷贝操作
用法(path和num都是数组):
path = num[:]
如 path = num[:] 中,
path只会创建num的浅层副本,即只复制num中的元素的引用,而不会复制嵌套对象本身。
什么意思呢?简单举例来说:
如果num是一维数组的话,浅拷贝与深拷贝一样,对数组path怎样操作都影响不到数组num。
path修改元素(num值不变):
如果num是二维或二维以上的数组的话,path只会复制num数组的表面,如果修改path中的元素,原始列表num中的对应元素也会被修改。但是,如果你对path整体进行修改(例如path.append([3,3])),则不会影响原始列表num。
path修改元素(num也会改变):
path增加元素(num值不变):
所以 [:] 浅拷贝的缺陷很明显,一旦拷贝嵌套列表(二维及二维以上),对复制的列表进行修改操作会影响原列表,无法恢复。
二:copy()浅拷贝操作:
这里主要扩充一下copy()函数的知识点,copy()函数的用法是:path = num.copy()。
path = num.copy()
path = num.copy() 与 path = num[:] 操作一样
这种方式也是对列表进行浅拷贝操作。它会创建一个新的列表path,但是该列表中的元素依然是原始列表num中元素的引用。因此,和path = num[:]一样,对path中的元素的修改会影响原始列表num中的对应元素,但对path整体的修改不会影响原始列表num。
三:标准库函数copy.deepcopy() 深拷贝(蓝桥杯可用)
用法:
import copypath = copy.deepcopy(num)
这种方式是对列表进行深拷贝操作。它会递归地复制原始列表num及其内部的所有对象,包括嵌套的列表、字典等。这样,创建的新列表path与原始列表num完全独立,对其中一个对象的修改不会影响另一个对象。深拷贝操作确保了复制后的对象与原始对象完全独立,是最安全的复制方式。
如图所示:
总结:
综上所述,path = num[:]和path = num.copy()是浅拷贝操作,会共享内部对象的引用,而path = copy.deepcopy(num)是深拷贝操作,会创建完全独立的副本。根据具体的需求,选择适合的复制方式来确保数据的安全性。
使用深拷贝就可以完美解决多维数组中对原数组的保留和修改问题。