Python中的深浅拷贝
-
浅拷贝
-
浅拷贝只拷贝一个外壳变成自己的,里面的内容是复用的被拷贝对象的。
list_1 = [1,2,3,[4,5,6,]] list_2 = list_1.copy() list_1.append(7) print(list_1, id(list_1)) print(list_2, id(list_2)) ''' # 输出结果: [1, 2, 3, [4, 5, 6], 7] 1341743330048 [1, 2, 3, [4, 5, 6]] 1341744017920 ''' # list_2拷贝的list_1,但当list_1改变列表中元素的时候,list_2却不发生改变,说明两个列表是开辟的不同内存空间,由两个列表的id()值不同,也可看出。 list_1 = [1,2,3,[4,5,6,]] list_2 = list_1.copy() list_1[0] = 0 list_1[-1].append(7) print(list_1, id(list_1)) print(list_2, id(list_2)) print(id(list_1[1])) print(id(list_2[1])) ''' 输出结果: [0, 2, 3, [4, 5, 6, 7]] 1835916030720 [1, 2, 3, [4, 5, 6, 7]] 1835916718592 140732296840896 140732296840896 ''' # 列表中的每个索引位置上的元素数据其实记录并不是真正的数据,而是数据的内存地址;当执行list_1.copy()后,会在内存中开辟一个新的空间存储list_2列表,list_2列表中的数据内存地址还会沿用list_1中的数据内存地址,即list_1和list_2中的数据都指向同一内存地址上的数据,因此,list_1和list_2的id()值不同,但列表中元素的id相同。但为什么改变list_1索引0上的值,list_2索引0上的值却不发生改变呢?那是因为list_1索引0上改变的是内存地址而非内存地址中的值。
-
-
深拷贝
-
原则上深拷贝不仅将外壳拷贝出来变成自己的,连里面的内容也都拷贝出来变成自己的。但Python做了一个优化,为了节省内存,将不可变的数据类型沿用同一内存地址上的数据;拷贝的可变数据类型则开辟新的内存空间,产生新的内存地址。
import copy list_1 = [1,2,3,[4,5,6,]] list_2 = copy.deepcopy(list_1) list_1[-1].append(7) print(list_1, id(list_1)) print(list_2, id(list_2)) print(id(list_1[1])) print(id(list_2[1])) ''' 输出结果: [1, 2, 3, [4, 5, 6, 7]] 1816231085888 [1, 2, 3, [4, 5, 6]] 1816231267776 140732296840896 140732296840896 '''
-
-
总结
- 浅拷贝:列表、字典嵌套的可变数据类型是同一个。列表切片数据浅拷贝。
- 深拷贝:列表、字典嵌套的可变数据类型不是同一个。