Python浅拷贝深拷贝之copy、deepcopy
笔记记录20221205:
个人总结:
1,两者基本区别不大;
2,在涉及到子对象时候,两者才有区别;
3,在涉及到子对象,且子对象的操作后内存地址没有发生变化(如下方代码:dic1['one'].append(4)),这时才有区别,即复制后的新对象,是copy的会发生变化、是deepcopy的不会发生变化
# 浅拷贝(copy()):拷贝父对象,不会拷贝对象内部的子对象。例子如下:
# 列表举例:li2进行copy了li1,li1变化,li2不会变化:
li1 = [1,2,3]
li2 = li1.copy()
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3] li2: [1, 2, 3]
li1.append(4)
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3, 4] li2: [1, 2, 3]
# 但是在上面的例子中看不出子对象父对象关系,那我们用下面这个例子:
'''
总结:
1,父对象发生了变化,复制后的新对象不会发生变化
2,当父对象没有发生变化,仅仅只是子对象发生了变化:
2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
'''
# 字典举例:
dic1 = {'one':[1,2,3],'two':[4,5,6]}
dic2 = dic1.copy()
# dic1: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]},
# dic1和dic2是独立的对象,但是它们的子对象[1,2,3]还是指向统一的对象,内存地址
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)
# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
# 2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
# 直接append,虽然子对象发生了变化,但是因为2.1:子对象的内存地址没有变化,那么dic2的键one的值,也随之发生改变
dic1['one'].append(4)
# dic1: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)
# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
# 2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
# 直接对字典对象进行操作,对one键进行重新赋值,那么满足2.2:子对象的内存地址有变化,这时dic2不会发生变化
dic1['one'] = [7,8,9]
# dic1: 2043613030208 {'one': [7, 8, 9], 'two': [4, 5, 6]}
# dic2: 2043612942528 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)
# 1,父对象发生了变化,复制的对象不会发生变化
dic3 = {'one':[1,2,3],'two':[4,5,6]}
dic4 = dic3.copy()
# 直接对字典对象进行操作,新增一个键值对,这时dic2不会发生变化
dic3['three'] = [7,8]
# dic3: {'one': [1, 2, 3], 'two': [4, 5, 6], 'three': [7, 8]}
# dic4: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic3:',dic3,'dic4:',dic4)
# 1,父对象发生了变化,复制的对象不会发生变化
dic5 = {'one':[1,2,3],'two':[4,5,6]}
dic6 = dic5.copy()
dic5.popitem() # 删除最后一个键值对
# dic5: {'one': [1, 2, 3]}
# dic6: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic5:',dic5,'dic6:',dic6)
# 深拷贝(deepcopy()):是copy模块中的方法,完全拷贝了子对象和父对象,例子如下:
# 深度拷贝, dic8完全拷贝了dic7父对象及其子对象,两者是完全独立的
from copy import deepcopy
dic7 = {'one':[1,2,3],'two':[4,5,6]}
dic8 = deepcopy(dic7)
dic7['one'].append(4)
# dic7: {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic8: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic7:',dic7,'dic8:',dic8)