直接拿代码说话吧
一.浅拷贝
1.1赋值拷贝
# 关于浅拷贝
# 浅拷贝的几种
# 1 赋值拷贝
# 赋值拷贝 只拷贝了对象的引用,修改拷贝对象的值也会对原来的值有影响
a = [1,2,3]
b = a
b.append(4)
print(a)
print(b)
print(id(a))
print(id(b))
"""
[1, 2, 3, 4]
[1, 2, 3, 4]
1962638078088
1962638078088
"""
1.2赋值拷贝的一些问题
import copy
# 浅拷贝
# 用copy模块.copy进行拷贝 只是拷贝了一个对象的顶层,里面的东西仍然拷贝的是引用
a = [1,2,3]
b = copy.copy(a)
# 在b中新增了一个元素
# 为什么不影响呢?
"""
a中有三个基本数据类型,b拷贝了a的最外层分配了一个新的空间。
里层内容拷贝的是引用,b总新增了一个基本数据与a没有关联,因为没有对a中数据进行修改
"""
b.append(4)
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
"""
[1, 2, 3]
[1, 2, 3, 4]
2423525240968
2423535521288
1467575312
1467575312
"""
1.3.1copy调用copy模块进行浅拷贝
import copy
# 浅拷贝
# 用copy模块.copy进行拷贝 只是拷贝了一个对象的顶层,里面的东西仍然拷贝的是引用
a = [1,2,3]
b = copy.copy(a)
# 我们修改b中的值a中的值会受到影响吗?
b[0] = 5
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
"""
[1, 2, 3]
[5, 2, 3]
2523524133000
2523543491016
1467575312
1467575440
"""
# 发现没有受到影响,因为通过赋值拷贝传递了引用,此时b[0]指向值为5的对象,与a无关
1.3.2
import copy
# 浅拷贝
a = [[1,2],[3,4]]
b = copy.copy(a)
b[0] = [1,2,3]# 与上同理不会改变原来的值
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
'''
[[1, 2], [3, 4]]
[[1, 2, 3], [3, 4]]
3235770114376
3235761245704
3235750965384
3235770264072
'''
1.4copy调用copy模块进行浅拷贝
import copy
# 浅拷贝 只是考虑了顶层的列表(分配了新的存储空间)
# 列表里的东西都拷贝的是引用
c = [1,2]
d = [3,4]
a = [c,d]
b = copy.copy(a)
c.append(5)
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
'''
[[1, 2, 5], [3, 4]]
[[1, 2, 5], [3, 4]]
1663393898696
1663385009672
1663374684296
1663374684296
'''
1.5对切片的拷贝
import copy
# 列表的切片赋值是浅拷贝还是深拷贝?
c = [1,2]
d = [3,4]
a = [c,d]
b = a[:]
c.append(3)
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
'''
[[1, 2, 3], [3, 4]]
[[1, 2, 3], [3, 4]]
1696674324872
1696666469640
1696655306888
1696655306888
'''
# 发现是浅拷贝,对新列表的操作也会对原来列表影响
# 在处理数据时,要考虑到对原数据的污染
二 深拷贝
2.1 用copy模块的deepcopy方法列表的深拷贝
import copy
import copy
# 深拷贝 是递归拷贝,它不会拷贝数据的引用 而是重新分配了存储空间
a = [[1,2],[3,4]]
b = copy.deepcopy(a)
b[0] = [1,2,3] # 深拷贝不会改变原来的值
print(a)
print(b)
print(id(a))
print(id(b))
print(id(a[0]))
print(id(b[0]))
'''
[[1, 2], [3, 4]]
[[1, 2, 3], [3, 4]]
2072156288456
2072168263112
2072168224904
2072156288584 #发现id值不相同,说明重新分配了存储空间
'''
2.2 用copy模块的copy方法字典的拷贝
import copy
# 字典的浅拷贝
a = {'age': 27,'name': 'zhangsan','list_age' : [12,24]}
b = copy.copy(a)
b['age'] = 100 # 赋值拷贝会影响
b['list_age'].append(23) # 对字典的浅拷贝内部仍然是拷贝的引用
print(a)
print(b)
print(id(a))
print(id(b))
2384697861968
2384697861248
import copy
# 字典的深拷贝
a = {'age': 27,'name': 'zhangsan','list_age' : [12,24]}
b = copy.deepcopy(a)
b['age'] = 100 # 赋值拷贝不会影响
b['list_age'].append(23)
print(a)
print(b)
print(id(a))
print(id(b))
三 深拷贝和浅拷贝之间的比较
import copy
a = [11,22]
b = (a,)
c = [b, ]
d = copy.copy(c)
a.append(33)
print(c)
print(d)
print(id(c))
print(id(d))
# 浅拷贝只是拷贝了最外层,里层拷贝了引用
'''
[([11, 22, 33],)]
[([11, 22, 33],)]
2866062314824
2866071179528
import copy
a = [11,22]
b = (a,)
c = [b, ]
d = copy.deepcopy(c)
a.append(33)
print(c)
print(d)
print(id(c))
print(id(d))
# 深拷贝只是拷贝了都重新分配了存储空间进行了拷贝
'''
[([11, 22, 33],)]
[([11, 22],)]
1970627436808
1970627350600
四 小结
在copy.copy方法中浅拷贝只是拷贝了顶层框架,并给顶层重新分配了存储空间,其他部分仍然拷贝的是引用
在copy.deepcopy方法中深拷贝,对所有东西进行递归拷贝,并全部重新分配了存储空间
赋值拷贝拷贝的是引用,拷贝数据和源数据的地址是相同的
对列表的切片后赋值拷贝的也是引用,对列表进行操作时要注意对原数据的污染