拷贝,原则上就是把数据分离,使得源数据和副本数据的修改互不影响。在Python中,拷贝是有深、浅之分的,如果使用的时候不注意,就可能产生意外的结果。其实这个是由于共享内存导致的结果。
一、不可变数据类型
Python中不可变数据类型包括整型、浮点数、布尔值、字符串、元组。
1、赋值
对不可变数据类型来说,等号赋值并不会在内存中创建新的地址,只是多了一个引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| a1 = 123 a2 = a1 print(id(a1), id(a2))
b1 = 1.123 b2 = b1 print(id(b1), id(b2))
c1 = 'hello' c2 = c1 print(id(c1), id(c2))
d1 = True d2 = d1 print(id(d1), id(d2))
e1 = (1, 2, 3, 'hkey') e2 = e1 print(id(e1), id(e2))
|
2、浅拷贝
对不可变数据类型使用浅拷贝,不会在内存中创建新的地址。
1 2 3 4 5 6
| import copy
a1 = 'hello' a2 = copy.copy(a1)
print(id(a1), id(a2))
|
3、深拷贝
对不可变数据类型使用深拷贝,不会在内存中创建新的地址。
1 2 3 4 5 6
| import copy
a1 = 'hello' a2 = copy.deepcopy(a1)
print(id(a1), id(a2))
|
二、可变数据类型
Python中可变数据类型包括列表、字典。
1、赋值
对可变数据类型来说,等号赋值并不会在内存中创建新的地址,只是多了一个引用。
1 2 3 4
| n1 = {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} n2 = n1
print(id(n1), id(n2))
|
2、浅拷贝
对可变数据类型使用浅拷贝,只将第一层结构拷贝到了新的内存地址,更深层的则没有。
1 2 3 4 5 6 7 8 9 10
| import copy
n1 = {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} n2 = copy.copy(n1) print('第一层字典的内存地址:') print(id(n1)) print(id(n2)) print('第二层嵌套的列表的内存地址:') print(id(n1['k3'])) print(id(n2['k3']))
|
3、深拷贝
对可变数据类型使用深拷贝,将各层结构都拷贝到了新的内存地址。注意,对于里面的最小元素,如数字和字符串,它们的地址还是不变的。
1 2 3 4 5 6 7 8 9 10
| import copy
n1 = {'k1': 'wu', 'k2': 123, 'k3': ['alex', 678]} n2 = copy.deepcopy(n1) print('第一层字典的内存地址:') print(id(n1)) print(id(n2)) print('第二层嵌套的列表的内存地址:') print(id(n1['k3'])) print(id(n2['k3']))
|