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

底层剖析Python深浅拷贝

发布时间:2020-12-20 10:11:04 所属栏目:Python 来源:网络整理
导读:拷贝的用途 拷贝就是 copy ,目的在于复制出一份一模一样的数据。使用相同的算法对于产生的数据有多种截然不同的用途时就可以使用 copy 技术,将 copy 出的各种副本去做各种不同的操作。 值得一提的是绝大部分编程语言中对于 copy 都有深浅拷贝的概念,所以

拷贝的用途

  拷贝就是copy,目的在于复制出一份一模一样的数据。使用相同的算法对于产生的数据有多种截然不同的用途时就可以使用copy技术,将copy出的各种副本去做各种不同的操作。

  值得一提的是绝大部分编程语言中对于copy都有深浅拷贝的概念,所以充分的理解本章节的知识也是在为今后学习其他编程语言少走弯路。

  在Python中,除开手动deepcopy(),其他的任何操作都是浅拷贝。

Python = 赋值示例

  好了,废话不多说。直接进入主题,上代码:

>>> # ==== = 赋值示例 ====
>>>
>>> li1 = ["a",b 注意存储的数据类型。第一层存储2个不可变类型,1个可变类型小容器(list),第二层存储2个不可变类型
>>> id(li1)   第一层,查看变量名所指向的列表(第一层容器)的内存地址id号
2324901133120
>>> id(li1[0])   第一层,查看第一层容器中的具体元素内存地址id号  
2324900663472
>>> id(li1[-1])   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
2324900812864
>>> li1
['',2]]
>>>  =============手动分割线=============
>>> li2 = li1
>>> id(li2)   第一层,查看第一层容器中的具体元素内存地址id号  
2324900663472
>>> id(li2[-1])   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
2324900812864
>>> li2   可以看到 li2 与li1 不管是第一层。还是第二层的内存地址id号都全部一样
[]]
>>>

  尝试修改li1,查看li2的变化:

>>> li1[0] = x"
>>> li1[-1][-1] = 20
>>>]]
>>> li2  可以看到li2随着li1而变化,不管是第一层还是第二层都跟着变化,因为内存引用都全部一样。
[]]
>>>

  赋值结论:

    本体            

      1.修改不可变类型数据(如:第一层的str

      2.修改可变数据类型中的数据(如:第二层小容器list中的数据)

  对应关系

    拷贝体

      1.不保持原本体中的值,跟随本体变化

      2.不保持原本体中的值,跟随本体变化

底层原理

image-20200801235711809

Python 浅拷贝示例

  浅拷贝,用到list数据类型自带的方法,copy()。我们来看一看会怎么样:

>>>  ==== 浅拷贝示例 ====
>>>
>>> li1 = [ 第一层,查看第一层容器中的具体元素内存地址id号
3120557838512
>>> id(li1[-1])   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
3120557987904
>>>=============手动分割线=============
>>> li2 = li1.copy()
>>> id(li2)   第一层,查看第一层容器中的具体元素内存地址id号
3120557838512
>>> id(li2[-1])   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
3120557987904
>>> li2   可以看到 li2 与li1 第一层的内存地址已经发生了变化。只有第二层的内存引用地址一样
[ li2 仅仅只有第二层小容器list中的值发生了变化。而第一层中的str不可变类型并没有发生变化
[]]
>>>

  浅拷贝结论:

    本体            

      1.修改不可变类型数据(如:第一层的str

      2.修改可变数据类型中的数据(如:第二层小容器list中的数据)

  对应关系

    拷贝体

      1.保持原本体中的值,不发生变化

      2.不保持原本体中的值,跟随本体变化

底层原理

image-20200801235556014

Python 深拷贝示例

  使用深拷贝需要导入Python的内置库,copy,具体使用方式还是看代码:

>>>  ==== 深拷贝示例 ====
>>>
>>> from copy import deepcopy   deep深度的意思,copy就拷贝。
>>> li1 = [ 注意存储的数据类型。第一层存储2个不可变类型,1个可变类型小容器(list),第二层存储2个不可变 类型
>>> id(li1)   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
3120558353280
>>>]]
>>>   deepcopy(li1)
>>> id(li2)   第二层(小容器id号),查看第一层容器中的小容器list的内存地址id号
3120558904448
>>> li2   li2 由于小容器也新生成了一个。所以即使li1小容器中的值发生改变,li2小容器中的值依然是原本的值
[]]
>>>

  深拷贝结论:

    本体            

      1.修改不可变类型数据(如:第一层的str

      2.修改可变数据类型中的数据(如:第二层小容器list中的数据)

  对应关系

    拷贝体

      1.保持原本体中的值,不发生变化

      2.保持原本体中的值,不发生变化

底层原理

image-20200801235449414

其他图示

?
b = a: 赋值引用,a 和 b 都指向同一个对象。

img

?
b = a.copy():浅拷贝,a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。

img

?
b = copy.deepcopy(a): 深度拷贝,a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。

(编辑:李大同)

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

    推荐文章
      热点阅读