引用vs拷贝
1.引用
赋值操作总是存储对象的引用,而不是这些对象的拷贝。引用的一大特点:可以在程序范围内任何地方传递大型对象而不必在中途产生拷贝。不过,因为赋值操作会产生相同对象的多个引用,需要意识到在原处修改可变对象时可能会影响到程序中其他地方对相同对象的其他引用。
2.拷贝
明确要求拷贝的几种方法:
(1)没有限制条件的分片表达式(L[:])能够复制序列
(2)字典copy方法(D.coopy())能够复制字典
(3)有些内置函数(例如:list())能够生成拷贝
(4)copy标准库模板能够生成完整拷贝
拷贝需要注意的地方:无条件值的分片以及字典copy方法只能做顶层复制。也就是说,不能够复制嵌套的数据结构。如果需要一个深层嵌套的数据结构的完整的、完全独立的拷贝,那么就要使用标准的copy模块。(如import copy X = copy.deepcopy(Y)对任意嵌套的对象Y做完整的复制。这些语句能够递归的遍历对象来复制它们所有的组成部分)
一个小例题:
L = [4, 5, 6] x = L * 2 Y = [L] * 2
若L[1] = 0, 则
X = [4, 5, 6, 4, 5, 6] ; Y = [[4, 0, 6], [4, 0, 6]];
假设Y = [L[:]] * 2, 则会和X的结果相同。
小知识点:
不可变类型不可以在原处改变。如果需要改变的话,得通过分片、合并等操作建一个新的对象。
如:T = (1, 2, 3)
T[2] = 4; #error
T = T[:2] + (4,) #ok:(1, 2, 4)