在python中很多时候需要进行复制的操作,比方说给一个变量赋值为另一个变量,这就是一个复制。
事实上,对于不同类型的对象,有的时候这种复制是深复制,有时候是浅复制。
下面在例子中具体介绍。
1、浅复制
顾名思义,浅复制就是浅浅地复制,只复制了它的表面,没有复制深层次的东西。就像是只复制了她好看的皮囊,没有复制到她独特的灵魂。
举个例子,列表的和字典就是浅复制。
1.1列表
lis = [1,2,3,4]
lis1 = lis[:3]
lis1[1] = 6
print('lis:',lis)
print('lis1:',lis1)
"""
out:
lis: [1, 2, 3, 4]
lis1: [1, 6, 3]
"""
可以发现,更改新变量中的内容,原始数据并没有变化,难道就这样以为它是深复制吗?
下面再来看:
lis = [1,2,3,4,[5,6]]
lis1 = lis[2:]
lis1[2][0] = 6
print('lis:',lis)
print('lis1:',lis1)
'''
out:
lis: [1, 2, 3, 4, [6, 6]]
lis1: [3, 4, [6, 6]]
'''
可以看到,修改新列表,原始数据也跟随变化了。
这是因为,列表的外层确实是复制了原始数据的值,但是内层列表仍然只是复制了原始数据的地址,它在新列表中保存的不是值而是指针。
当然,如果将[5,6]重新赋值为一个数字,或者一个新的列表,那么都改变了指针的指向,仍然不会改变原始数据。
1.2字典
字典和列表是一样的道理,下面举个简单的例子进行说明。
dic = {'name':'jack','age':18}
dic1 = dic.copy()
dic1['name'] = 'rose'
print('dic:',dic)
print('dic1',dic1)
'''
out:
dic: {'name': 'jack', 'age': 18}
dic1 {'name': 'rose', 'age': 18}
'''
dic = {'name':'jack','age':18,'id':{'sid':1,'bid':2}}
dic1 = dic.copy()
print('更改之前的:\ndic:',dic)
dic1['id']['sid'] = 66
print('更改之后的:\ndic:',dic)
print('dic1',dic1)
'''
更改之前的:
dic: {'name': 'jack', 'age': 18, 'id': {'sid': 1, 'bid': 2}}
更改之后的:
dic: {'name': 'jack', 'age': 18, 'id': {'sid': 66, 'bid': 2}}
dic1 {'name': 'jack', 'age': 18, 'id': {'sid': 66, 'bid': 2}}
'''
请读者自行体会。
2、深复制
下面把上面的例子重新展现,只把复制改成深复制。
2.1 列表
lis = [1,2,3,4,[5,6]]
import copy
lis1 = copy.deepcopy(lis[2:])
lis1[2][0] = 6
print('lis:',lis)
print('lis1:',lis1)
'''
lis: [1, 2, 3, 4, [5, 6]]
lis1: [3, 4, [6, 6]]
'''
区别显然易见。(对比1.1的第二个代码块)
2.2 字典
dic = {'name':'jack','age':18,'id':{'sid':1,'bid':2}}
import copy
dic1 = copy.deepcopy(dic)
print('更改之前的:\ndic:',dic)
dic1['id']['sid'] = 66
print('更改之后的:\ndic:',dic)
print('dic1',dic1)
'''
更改之前的:
dic: {'name': 'jack', 'age': 18, 'id': {'sid': 1, 'bid': 2}}
更改之后的:
dic: {'name': 'jack', 'age': 18, 'id': {'sid': 1, 'bid': 2}}
dic1 {'name': 'jack', 'age': 18, 'id': {'sid': 66, 'bid': 2}}
'''
对比1.2的第二个代码块。
3、总结
-
浅复制只有外层复制了对象的值,内层是指向了原数据的指针。原变量有可能会跟随新变量变化。
-
深复制所有层都是复制了对象的值,开辟了新的id,原变量不可能跟随新变量变化。