Python之深拷贝和浅拷贝
"""
***赋值, 深拷贝和浅拷贝的区别?(python中如何拷贝一个对象?)
- 直接赋值(li1 = li): 只传递对象的引用, li1指向对象li的内存地址空间,
因此, 原有列表li改变, 被赋值的li1也会做相应的改变.
- 浅拷贝(三种实现方式 eg: li2=li.copy()):li和li2的内存地址不同,
但是子对象的内存地址相同, 因此,原始数据改变 , 子对象也改变.
- 深拷贝(import copy, eg: li3=copy.deepcopy(li)), li和li3的内存地址不同,
包含子对象的拷贝, 所以原始对象改变并不会造成深拷贝里面任何子项的改变.
*** 当深拷贝和浅拷贝, 针对的对象全部是不可变数据类型时, 两者效果相同;
*** 当深拷贝和浅拷贝, 针对的对象包含是可变数据类型时, 两者才有上述区别;
li = [1,2,3]
li1 = li
li.append(4)
li
[1, 2, 3, 4]
li1
[1, 2, 3, 4]
li2 = li[:]
li3 = li.copy()
li
[1, 2, 3, 4]
li.append(5)
li
[1, 2, 3, 4, 5]
li1
[1, 2, 3, 4, 5]
li2
[1, 2, 3, 4]
li3
[1, 2, 3, 4]
"""
# 列表里面嵌套列表
"""
li = [['a', 'b'], 2, 3, 4]
li2 = li[:]
li3 = li.copy()
id(li), id(li2), id(li3)
(139714653000840, 139714653000968, 139714653000904)
li.append(5)
li, li2, li3
([['a', 'b'], 2, 3, 4, 5], [['a', 'b'], 2, 3, 4], [['a', 'b'], 2, 3, 4]) ##此操作针对子对象中的数值,数值是不可变数据类型,所以值不会随之改变##
li[0].append('c')
li, li2, li3
([['a', 'b', 'c'], 2, 3, 4, 5], [['a', 'b', 'c'], 2, 3, 4], [['a', 'b', 'c'], 2, 3, 4]) ##此操作针对子对象的列表,列表是可变数据类型,所以值会随之改变##
li = [['a', 'b'], 1,2]
li2 = li.copy()
li
[['a', 'b'], 1, 2]
li2
[['a', 'b'], 1, 2]
id(li[0])
140330900099656
id(li2[0])
140330900099656
import copy
li
[['a', 'b'], 1, 2]
li2
[['a', 'b'], 1, 2]
li3 = copy.copy(li)
li4 = copy.deepcopy(li)
li
[['a', 'b'], 1, 2]
li4
[['a', 'b'], 1, 2]
id(li[0])
140136482447944
id(li3[0])
140136482447944 #浅拷贝,子对象内存地址相同
id(li4[0])
140136361969928 #深拷贝,子对象内存地址不同
"""
# 所有的数值类型和布尔类型, str是不可变数据类型,
# list是可变数据类型;
# 浅拷贝的实现:
# - li.copy()
# - li[:]
# - copy.copy(li)
# 实现深拷贝:
# - copy.deepcopy(li)