加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Python3 深拷贝和浅拷贝的区别和原理

发布时间:2021-07-06 05:58:41 所属栏目:大数据 来源: https://blog.csdn.net/yilovex
导读:首先,我们知道在 Python3 中,有 6 个标准的数据类型,他们又分为可变和不可变 不可变数据类型(3个) Number(数字) String(字符串) Tuple(元组) 可变数据类型(3个) List(列表) Dictionary(字典) Set(集合) 在 Python 中,其实是没有那种传统

首先,我们知道在 Python3 中,有 6 个标准的数据类型,他们又分为可变和不可变

不可变数据类型(3个)

  • Number(数字)

  • String(字符串)

  • Tuple(元组)

可变数据类型(3个)

  • List(列表)

  • Dictionary(字典)

  • Set(集合)

在 Python 中,其实是没有那种传统意义上的变量,我们通常说的变量其实是一个标签,或者是一个指针变量,因为它保存的是变量的一个地址

对于不可变类型,赋值、浅拷贝、深拷贝其实都是创建一个标签,指向了变量的地址,它的 id 都是一样的。而当我们改变其中一个标签的值的时候,其实就是将这个标签重新指向一个新的地址,旧的变量的引用计数会减一,随之它的 id 也会变化

In [1]: from copy import copy,deepcopy

In [2]: a = 'a,b,c,d'

In [3]: b = a

In [4]: c = copy(a)

In [5]: d = deepcopy(a)

In [6]: a,d
Out[6]: ('a,d','a,d')

In [7]: id(a),id(b),id(c),id(d)
Out[7]: (4592638320,4592638320,4592638320)

In [8]: a = '1,2,3,4'

In [9]: a,d
Out[9]: ('1,4',d')

In [10]: id(a),id(d)
Out[10]: (4592787504,4592638320)

对于可变类型,赋值是创建一个标签,和不可变类型一致

浅拷贝的时候,标签会重新开辟一个新的地址,不占用被拷贝对象的引用计数。新的标签也是指向变量(或者叫数组)的地址,它们 id 是不同的

深拷贝的时候,标签会重新开辟一个新的地址,并将被拷贝的对象放入新的地址。此时,内存地址中就会有两份一模一样的数据,但是地址不同, 当然,它们 id 也是不同的

In [1]: from copy import copy,deepcopy

In [2]: a = [1,[2,3],'4']

In [3]: b = a

In [4]: c = copy(a)

In [5]: d = deepcopy(a)

In [6]: a,d
Out[6]: ([1,'4'],[1,'4'])

In [7]: id(a),id(d)
Out[7]: (4394796232,4394796232,4397213000,4397312072)

In [8]: a[1][0] = 0

In [9]: a,d
Out[9]: ([1,[0,'4'])

In [10]: id(a),id(d)
Out[10]: (4394796232,4397312072)

有一点需要注意的是,当我们重新给不可变类型的标签赋值时,它会释放标签的引用计数,并且改变它的地址。但是下列第 11 行代码,我将它的标签重新赋值后,它的地址还是没变(13行),这是为什么呢?

In [11]: a[0] = 0

In [12]: a,d
Out[12]: ([0,'4'])

In [13]: id(a),id(d)
Out[13]: (4394796232,4397312072)

这是因为刚刚我们查看的是整个数组的 id,而不是某一个元素的 id

重新给数组中的某一个元素赋值,当我们单独查看它的 id 时,它的 id 已经发生了变化(14,17行)

In [14]: id(a[0])
Out[14]: 4365118432

In [15]: a[0] = 5

In [16]: id(a),id(d)
Out[16]: (4394796232,4397312072)

In [17]: id(a[0])
Out[17]: 4365118592

对于 Python 的浅拷贝和深拷贝其实是针对于那些可变类型的,因为对不可变类型没有意义,赋值操作就足够了

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读