ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python深拷贝和浅拷贝

2022-07-27 14:00:42  阅读:163  来源: 互联网

标签:python 数据类型 地址 print 拷贝 copy id


目录

简介

最直观的理解就是:
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

总结

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

标签:python,数据类型,地址,print,拷贝,copy,id
来源: https://www.cnblogs.com/even160941/p/16524598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有