python深拷贝和浅拷贝详解
2018-08-14 本文已影响0人
陆_志东
对于python来说,有两种拷贝类型,浅拷贝和深拷贝
但要注意的是= 不是浅拷贝也不是深拷贝,赋值是新建了一个引用
赋值
a = 1
b = 1
print(id(a)==id(b))
>>True
c = [1,2]
d = c
print(id(c)==id(d))
>>True
可变类型和不可变类型
# 可变类型: 列表,字典,集合
# 不可变类型: 整数,字符串,元祖,布尔
# 对于不可变类型来说,浅拷贝和深拷贝没有区别,都是深拷贝
# 注意虽然是深拷贝,但是对于不可变类型来说,复制一份会浪费资源,因为它是不可变
# 所以没必要复制一份,python的做法是为不可变对象创建一个引用
# 对于可变类型来说,浅拷贝是最外层次的拷贝,深拷贝就是深拷贝
浅拷贝
copy.copy() 和 列表的切片功能都是浅拷贝
list1 = [[1,2],2,3]
list2 = list1[:]
print(id(list1)==id(list2)) #外层比较
>>False # 因为比较的是最外层,所以False
print(id(list1[0])==id(list2[0]))
>>True # 浅拷贝只拷贝了外层,内层比较为True
print(id(list1[1])==id(list2[1]))
>>True #
list1.remove(3) # 列表是属于外层,这是外层操作,所以不影响另一个变量
# 为什么属于外层操作? 因为remove是外层列表的方法
print(list1)
>>[[1, 2], 2]
print(list2)
>>[[1, 2], 2, 3]
list1[0].append(3) # 内层操作
print(list1)
>>[[1, 2, 3], 2]
print(list2)
>>[[1, 2, 3], 2, 3]
深拷贝
注意深拷贝只有一种方法 copy.deepcopy()
import copy
list1 = [["a",2],2,3]
list2 = copy.deepcopy(list1)
print(id(list1)==id(list2))
>>False
print(id(list1[0])==id(list2[0]))
>>False
# 注意这里有一个坑, 下面的两个比较是True,不是False,
# 这是因为对于不可变对象,python不会浪费资源去复制一份,而是创建一个引用去赋值
print(id(list1[0][0])==id(list2[0][0]))
>>True
print(id(list1[0][1])==id(list2[0][1]))
>>True
print(id(False)==id(False))
>>True