1. 理解名词
可变对象:列表、字典、集合
不可变对象:数字、字符串、元组
拷贝:复制一个新的对象,新增一块内存空间
引用:不会新增对象,不会开辟新的内存空间,只是多了一个引用
2. 对【不可变对象】进行拷贝,是新增一个对象,即另辟一块内存空间,内存地址不同,一个改变互不影响。 本文总结是对【可变对象】的拷贝。
2.1. 赋值
listA = [1,2,3,['a','b']]
listB = listA
listB.append(5)
listB[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA,id(listA)))
print('ListB值为{0},内存地址id为{1}'.format(listB,id(listB)))
结果:
ListA值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为37202504
ListB值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为37202504
现象:父对象和子对象全部相同, id也相同
总结:1个对象赋值给另一个变量时,没有拷贝对象,只是拷贝对象的一个引用
2.2 浅拷贝
a)切片
listC = listA[:]
listC.append(5)
listC[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA,id(listA)))
print('ListC值为{0},内存地址id为{1}'.format(listC,id(listC)))
结果:
ListA值为[1, 2, 3, ['ax', 'b']],内存地址id为42248776
ListC值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42249608
现象:父对象不同,子对象相同,id不同
总结:切片只是拷贝父对象,包含的子对象只是引用,不拷贝,id不同
b) copy
listD = listA.copy()
listD.append(5)
listD[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA, id(listA)))
print('ListD值为{0},内存地址id为{1}'.format(listD, id(listD)))
结果:
ListA值为[1, 2, 3, ['ax', 'b']],内存地址id为42576456
ListD值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42577288
现象:同切片(现象:父对象不同,子对象相同,id不同)
总结:copy只是拷贝父对象,包含的子对象只是引用,不拷贝,id不同
2.3 深拷贝(注意要导入import copy模块)
listE = copy.deepcopy(listA)
listE.append(5)
listE[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA, id(listA)))
print('ListE值为{0},内存地址id为{1}'.format(listE, id(listE)))
结果:
ListA值为[1, 2, 3, ['a', 'b']],内存地址id为42510920
ListE值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42511752
现象:父对象与子对象不同,id不同
总结:深拷贝是对对象及子对象进行拷贝,不是引用。所以互不影响