Python正课14 —— 深浅Copy
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/12450407.html
一:引子
如果把一个列表的值引用给另一个列表,它们的值和id是否相等?
l1 = ['xxq',18,'male'] #定义列表l1
l2 = l1 #把l1的值引用给l2
print(l1) #输出l1的内容
print(l2) #输出l2的内容
print(id(l1)) #输出l1的id
print(id(l2)) #输出l2的id
['xxq', 18, 'male']
['xxq', 18, 'male']
58970184
58970184
这里可以看出,他们输出的内容完全相等。
l1 = ['xxq',18,'male']
l2 = l1
l1[0] = 'qwe' #将l1的第一个值改变
print(l1)
print(l2)
print(id(l1))
print(id(l2))
['qwe', 18, 'male']
['qwe', 18, 'male']
17354824
17354824
这里可以看出:二者分隔不开,l1改l2也跟着改,因为指向的就是同一个地址。
但是,如果想要把2个列表完全独立开,互不影响,该怎么操作呢?
二:浅Copy
浅Copy:是把原列表第一层的内存地址不加区分完全copy一份给新列表
小白鼠实验:
l1 = ['xxq',18,'male']
l3 = l1.copy()
print(l1)
print(l3)
print(id(l1))
print(id(l3))
['xxq', 18, 'male']
['xxq', 18, 'male']
30396488
60089832
由此可以看出:l3拷贝了l1的值,但是l3和l1的id是不同的。
实验1:
对于不可变类型的赋值,都是产生了新值,让原列表的索引指向新的内存地址,并不会影响新列表。
l1 = ['xxq',18,'male']
l3 = l1.copy()
l1[0] = 'asd'
l3[0] = 'zxc'
print(l1)
print(l3)
print(id(l1))
print(id(l3))
print(id(l1[0]),id(l1[1]),id(l1[2]))
print(id(l3[0]),id(l3[1]),id(l3[2]))
['asd', 18, 'male']
['zxc', 18, 'male']
11718728
13362664
13484608 1494739136 13484576
13484640 1494739136 13484576
Process finished with exit code 0
实验2:
但对于可变类型,我们可以改变可变类型中包含的值,但内存地址不变即原列表的索引指向仍然指向原来的内存地址,于是新列表也跟着一起受影响,如下:
这个例子中,l4浅Copy了l1,可以看出l1和l4列表内的元素内存地址相同,列表内存地址不同
l1 = ['xxq',18,[1,2]]
l4 = l1.copy()
print(l1)
print(l4)
print(id(l1))
print(id(l4))
print(id(l1[0]),id(l1[1]),id(l1[2]),id(l1[2][0]),id(l1[2][1]))
print(id(l4[0]),id(l4[1]),id(l1[2]),id(l4[2][0]),id(l4[2][1]))
['xxq', 18, [10, 2]]
['xxq', 18, [10, 2]]
11724264
11724968
57259360 1494739136 55889992 1494738864 1494738880
57259360 1494739136 55889992 1494738864 1494738880
这个例子中,l4浅Copy了l1,并且l1和l4列表中的列表元素值改变,可以看出l1和l4列表内的元素内存地址相同,列表内存地址不同
l1 = ['xxq',18,[1,2]]
l4 = l1.copy()
l1[2][0] = 20
l4[2][1] = 10
print(l1)
print(l4)
print(id(l1))
print(id(l4))
print(id(l1[0]),id(l1[1]),id(l1[2]),id(l1[2][0]),id(l1[2][1]))
print(id(l4[0]),id(l4[1]),id(l1[2]),id(l4[2][0]),id(l4[2][1]))
['xxq', 18, [20, 10]]
['xxq', 18, [20, 10]]
19654120
19654824
19777088 1494739136 18272328 1494739168 1494739008
19777088 1494739136 18272328 1494739168 1494739008
综合实验1和实验2可以得出,要想copy得到的新列表与原列表的改操作完全独立开
必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深copy
三:深Copy
要使用深Copy,要先导入库:
import copy
然后使用
import copy
list1=[
'egon',
'lxx',
[1,2]
]
list3=copy.deepcopy(list1)
# print(id(list1))
# print(id(list3))
# print(list3)
# 不可变 不可变 可变
# print(id(list1[0]),id(list1[1]),id(list1[2]))
# print(id(list3[0]),id(list3[1]),id(list3[2]))
'''
4497919088 4498367856 4498449216
4497919088 4498367856 4498595328
'''
# print(list3)
# print(id(list1[2][0]),id(list1[2][1]))
# print(id(list3[2][0]),id(list3[2][1]))
list1[0]='EGON'
list1[1]='LXX'
list1[2][0]=111
list1[2][1]=222
# print(list1)
print(list3)