python深拷贝和浅拷贝


目录

简介

最直观的理解就是:
1.深拷贝,拷贝的程度深,自己新开辟了一块内存,将被拷贝内容全部拷贝过来了;
2.浅拷贝,拷贝的程度浅,只拷贝原数据的首地址,然后通过原数据的首地址,去获取内容。
两者的优缺点对比:
(1)深拷贝拷贝程度高,将原数据复制到新的内存空间中。改变拷贝后的内容不影响原数据内容。但是深拷贝耗时长,且占用内存空间。
(2)浅拷贝拷贝程度低,只复制原数据的地址。其实是将副本的地址指向原数据地址。修改副本内容,是通过当前地址指向原数据地址,去修改。所以修改副本内容会影响到原数据内容。但是浅拷贝耗时短,占用内存空间少。

浅拷贝

有一层数据类型,且数据类型时可变数据类型,例如:列表、字典

import copy
a = [1,2,3]
b = copy.copy(a)
print(a)
# [1, 2, 3]
print(b)
# [1, 2, 3]

# 地址不一致
print(id(a))
# 1579517559496
print(id(b))
# 1579517560200

a.append(4)
print(a)
# [1, 2, 3, 4]
print(b)
# [1, 2, 3]

有一层数据类型,且数据类型时不可变数据类型,例如:元组、字符串

import copy
a = (6,7,8)
b = copy.copy(a)
print(a)
# (6, 7, 8)
print(b)
# (6, 7, 8)
# 地址一致
print(id(a))
# 2593238617544
print(id(b))
# 2593238617544

有两层数据类型,外层为可变数据类型,内层为可变数据类型

import copy
a = [1,2]
b = [3,4]
c = [a,b]
d = copy.copy(c)
print(c)
[[1, 2], [3, 4]]
print(d)
[[1, 2], [3, 4]]

print(id(c))
# 2280002580808
# 外层地址改变
print(id(d))
# 2280002580744
print(id(a))
# 2280002580936
print(id(b))
# 2280002581768

# 内层地址不变
print(id(c[0]))
# 2280002580936
print(id(c[1]))
# 2280002581768
print(id(d[0]))
# 2280002580936
print(id(d[1]))
# 2280002581768

有两层数据类型,外层为可变数据类型,内层为不可变数据类型

import copy
a = (7,8)
b = (9,0)
c = [a,b]
d = copy.copy(c)
print(c)
# [(7, 8), (9, 0)]
print(d)
# [(7, 8), (9, 0)]
print(id(a))
# 2064778398344
print(id(b))
# 2064778398472
print(id(c))
# 2064778597512

# 外层地址改变
print(id(d))
# 2064778598856
# 内层地址不变
print(id(c[0]))
# 2064778398344
print(id(d[0]))
# 2064778398344
print(id(c[1]))
# 2064778398472
print(id(d[1]))
# 2064778398472

有两层数据类型,外层为不可变数据类型,内层为不可变数据类型

import copy
a = (1,2)
b = (3,4)
c = (a,b)
d = copy.copy(c)
print(c)
# ((1, 2), (3, 4))
print(d)
# ((1, 2), (3, 4))

print(id(a))
# 1933760334536
print(id(b))
# 1933760334664

# 外层地址不变 
print(id(c))
# 1933760521736
print(id(d))
# 1933760521736

# 内层地址不变
print(id(c[0]))
# 1933760334536
print(id(c[1]))
# 1933760334664
print(id(d[0]))
# 1933760334536
print(id(d[1]))
# 1933760334664

有两层数据类型,外层为不可变数据类型,内层为可变数据类型

import copy
a = [1,2]
b = [3,4]
c = (a,b)
d = copy.copy(c)
print(c)
# ([1, 2], [3, 4])
print(d)
# ([1, 2], [3, 4])
print(id(a))
# 2098312709128
print(id(b))
# 2098312709960
# 外层地址不变
print(id(c))
# 2098312709512
print(id(d))
# 2098312709512

# 内层地址不变
print(id(c[0]))
# 2098312709128
print(id(c[1]))
# 2098312709960
print(id(d[0]))
# 2098312709128
print(id(d[1]))
# 2098312709960

深拷贝

有一层数据类型,且数据类型时可变数据类型,例如:列表、字典

import copy
a = [1,2]
b = copy.deepcopy(a)
print(a)
# [1, 2]
print(b)
# [1, 2]

# 地址发生改变
print(id(a))
# 2712262157064
print(id(b))
# 2712262157832

有一层数据类型,且数据类型时不可变数据类型,例如:元组、字符串

import copy
a = (1,2)
b = copy.deepcopy(a)
print(a)
# (1, 2)
print(b)
# (1, 2)

# 地址未改变
print(id(a))
# 2372779051400
print(id(b))
# 2372779051400

有两层数据类型,外层为可变数据类型,内层为可变数据类型

import copy
a = [1,2]
b = [3,4]
c = [a,b]
d = copy.deepcopy(c)
print(c)
# [[1, 2], [3, 4]]
print(d)
# [[1, 2], [3, 4]]
print(id(a))
# 2044073358024
print(id(b))
# 2044073358984

# 外层地址不变
print(id(c))
# 2044073357896
print(id(d))
# 2044073358856

# 内层地址改变
print(id(c[0]))
# 2044073358024
print(id(c[1]))
# 2044073358984
print(id(d[0]))
# 2044073357832
print(id(d[1]))
# 2044072936328

有两层数据类型,外层为可变数据类型,内层为不可变数据类型

import copy
a = (1,2)
b = (3,4)
c = [a,b]
d = copy.deepcopy(c)
print(c)
# [(1, 2), (3, 4)]
print(d)
# [(1, 2), (3, 4)]
print(id(a))
# 2197363967752
print(id(b))
# 2197363967880

# 外层地址改变
print(id(c))
# 2197364167112
print(id(d))
# 2197364168520

# 内层地址不变
print(id(c[0]))
# 2197363967752
print(id(c[1]))
# 2197363967880
print(id(d[0]))
# 2197363967752
print(id(d[1]))
# 2197363967880

有两层数据类型,外层为不可变数据类型,内层为不可变数据类型

import copy
a = (1,2)
b = (3,4)
c = (a,b)
d = copy.deepcopy(c)
print(c)
# ((1, 2), (3, 4))
print(d)
# ((1, 2), (3, 4))
print(id(a))
# 2582331737992
print(id(b))
# 2582331738120

# 外层地址不变
print(id(c))
# 2582331942280
print(id(d))
# 2582331942280

# 内层地址不变
print(id(c[0]))
# 2582331737992
print(id(c[1]))
# 2582331738120
print(id(d[0]))
# 2582331737992
print(id(d[1]))
# 2582331738120

有两层数据类型,外层为不可变数据类型,内层为可变数据类型

import copy
a = [1,2]
b = [3,4]
c = (a,b)
d = copy.deepcopy(c)
print(c)
# ([1, 2], [3, 4])
print(d)
# ([1, 2], [3, 4])
print(id(a))
# 1404187259528
print(id(b))
# 1404187260424

# 外层地址改变
print(id(c))
# 1404187259976
print(id(d))
# 1404187259784

# 内层地址改变
print(id(c[0]))
# 1404187259528
print(id(c[1]))
# 1404187260424
print(id(d[0]))
# 1404187259336
print(id(d[1]))
# 1404187059400

总结

浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
当内层为可变数据类型时,深拷贝后内层外层地址均发生改变。当内层为不可变数据类型时,外层不管是可变还是不可变数据类型,使用深拷贝,都不会改变内层地址,只会改变外层地址。
使用浅拷贝是只能在外层数据类型为可变数据类型时,才能改变外层地址。而内层地址,无论是否为可变数据类型还是不可变数据类型,使用浅拷贝都不会改变内层数据类型地址。

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/277307.html

(0)
上一篇 2022年7月27日
下一篇 2022年7月27日

相关推荐

发表回复

登录后才能评论