前言
本系列博文为Python编程的精粹和要点,并不是python编程入门笔记,适合有一定编程经验的朋友。
知识要点:
- 引用和拷贝
- 顶层拷贝(浅拷贝)和嵌套拷贝(深拷贝)
参考《Python学习手册》第四版。
python中的赋值操作一般都是储存对象的引用,而不是这些对象的拷贝,这样做第一可以节约空间,第二可以提升效率,但使用引用的方式的话,如果改变原来的对象中的值,那么所有引用此对象的地方都会改变。
如果想在使用时确实是要拷贝,而不是引用,那么可通过分片、copy或类似list这样的内置函数等方式实现。如果想实现深拷贝,那么需要import copy,然后使用copy.deepcopy()实现。
下面看例子。
引用
使用引用的话,改变原始对象的内容,那么引用的它的地方也随着改变。
x = [1,2,3]
L = ['a', x, 'b']
print(L) #['a', [1, 2, 3], 'b']
x[1] = 'new'
print(L) #['a', [1, 'new', 3], 'b']
拷贝
使用拷贝的话,每个对象都是独立的,改变原始对象的值并不会改变拷贝后的内容。
x = [1,2,3]
L = ['a', x.copy(), 'b'] #因为使用了copy(),所以存放在L中的x是x的一个副本,而不是引用,这样改变原始x的值就不会影响L中的X。
# 除了使用copy()外,还可直接使用x[:]分片,或者list(x)生成副本。
#比如:L = ['a', x[:], 'b']和L = ['a', list(x), 'b']
print(L) #['a', [1, 2, 3], 'b']
x[1] = 'new'
print(x) #[1, 'new', 3], x本身已经改变了,但L中的x并不会改变
print(L) #['a', [1, 2, 3], 'b']
顶层拷贝(浅拷贝)
分片和copy方法只能做到顶层拷贝,或者称为浅拷贝,也就是说,不能够拷贝嵌套的数据结构。
x = [1,2,3]
L = ['a', x, 'b']
z = L.copy()#因为copy是顶层拷贝,只是生成了L的复本,但L副本中的x还是引用,改变x的值,那么L和z中的x也会对应的变化。
print("1:", z) #['a', [1, 2, 3], 'b']
x[2] = 'new_c'
print("2:", z) #['a', [1, 2, 'new_c'], 'b']
那么要直接拷贝x这种嵌套的对象,那么怎么办呢?这就要使用到嵌套拷贝。
嵌套拷贝(深拷贝)
嵌套拷贝可对对象的任意嵌套数据结构做拷贝。C语言中要实现嵌套拷贝是很麻烦的事,python使用一个现成的方法就可以了。
x = [1,2,3]
L = ['a', x, 'b']
import copy
z = copy.deepcopy(L)#因为使用的是嵌套拷贝,z为L一个副本,嵌套的x也是一个副本,所以改变x不会改变z中对应的值。
print("1:", z) #['a', [1, 2, 3], 'b']
x[2] = 'new_c'
print("2:", z) # ['a', [1, 2, 3], 'b']