Python中什么是深拷贝和浅拷贝且有什么区别

时间:2021-07-19 22:04:00

浅拷贝:

>>> a = [1, 2, 3]
>>> b = a
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>> id(a)
2154993843464
>>> id(b)
2154993843464

浅拷贝把a 赋值给了b,并不是直接再给b来了一个列表而是a和b都指向了同一个地址。

深拷贝:
使用copy模块下的deepcopy()来完成深拷贝

>>> import copy
>>> a = [1, 2, 3]
>>> b = copy.deepcopy(a)
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>> id(a)
2154997247496
>>> id(b)
2154997247688

深拷贝浅拷贝的区别
浅拷贝:

a = [1, 2, 3]
b = a
print(f"{a}")
print(f"{b}")
a.append(888)
print("添加后的数据:")
print(f"{a}")
print(f"{b}")

执行结果:
	[1, 2, 3]
	[1, 2, 3]
	添加后的数据:
	[1, 2, 3, 888]
	[1, 2, 3, 888]

深拷贝:

import copy

a = [1, 2, 3]
b = copy.deepcopy(a)
print(f"{a}")
print(f"{b}")
a.append(888)
print("添加后的数据:")
print(f"{a}")
print(f"{b}")

执行结果:
	[1, 2, 3]
	[1, 2, 3]
	添加后的数据:
	[1, 2, 3, 888]
	[1, 2, 3]  # <------区别在此

从上面的代码可以看出浅拷贝变更被拷贝对象的内容,拷贝方也会随之更改,而深拷贝则不受影响。

多层拷贝

import copy

a = [1, 2, 3]
b = [1, 2, 3]
c = [a, b]

# 浅拷贝
d = c
print("--------华丽的分割线--------")
print(f"c -> {id(c)}")
print(f"d -> {id(d)}")
print("--------华丽的分割线--------")

# 深拷贝
e = copy.deepcopy(c)  # deep 深
print(f"c -> {id(c)}")
print(f"e -> {id(e)}")
print("--------华丽的分割线--------")

# 现在这个e到底是拷贝的c还是a和b呢

# 开始验证
c[0].append("我是新来的")
print(c[0])
print(e[0])

执行结果:
	--------华丽的分割线--------
	c -> 2133324736584
	d -> 2133324736584
	--------华丽的分割线--------
	c -> 2133324736584
	e -> 2133324736520
	--------华丽的分割线--------
	[1, 2, 3, '我是新来的']
	[1, 2, 3]  # 未变动证明直接对a 和 b进行了一份深拷贝,而不是对c进行了一份拷贝

注意: 多层拷贝时使用copy.deepcopy()会直接跟着引用走,拷贝最终指向【如果使用的是e = copy.copy©就只会拷贝括号中的对象©,不会拷贝到上一层不会拷贝最终指向】,如果拷贝的是不可变数据类型(如:元组)将不能进行深拷贝

总结:
当需要数据共享时使用浅拷贝,数据独立不进行共享时使用深拷贝