python中的深浅烤备

筅森魡賤 提交于 2019-12-26 16:05:31

深浅拷贝

Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果
其实这个是由于共享内存导致的结果

拷贝:原则上就是把数据分离出来,复制其数据,并以后修改互不影响。

先看 一个非拷贝的例子

赋值:数据完全共享(赋值是在内存中指向同一个对象,如果是可变(mutable)类型,比如列表,修改其中一个,另一个必定改变

如果是不可变类型(immutable),比如字符串,修改了其中一个,另一个并不会改变

深拷贝是对于一个对象所有层次的拷贝(递归)copy.deepcopy
浅拷贝是对于一个对象的顶层拷贝;通俗的理解是:拷贝了引用,并没有拷贝内容.copy.copy

要想知道两者的区别,首先要知道什么是可变类型和不可变类型?

不可变类型:整型,长整型,浮点数,复数,布尔,字符串,元组
可变类型:列表,字典。

深浅拷贝有什么区别那?

1、如果用copy.copy、copy.deepcopy对一个全部都是不可变类型的数据进行拷贝,那么它们结果相同,都是引用指向;
2、如果拷贝的是一个拥有不可变类型的数据,即使元组是最顶层,那么deepcopy依然是深拷贝,而copy.copy还是指向

3、基本上只要不是我们自已手动调用的deepcopy方法都是浅拷贝,切片拷贝字典拷贝都是浅拷贝,而有些内置函数可以生成拷贝(list),属于深拷贝:a = list(range(10))

直接赋值(li1 = li): 只传递对象的引用, li1指向对象li的内存地址空间,
因此, 原有列表li改变, 被赋值的li1也会做相应的改变.

浅拷贝:li和li2的内存地址不同,但是子对象的内存地址相同, 因此,原始数据改变 , 子对象也改变.

深拷贝(import copy, eg: li3=copy.deepcopy(li)), li和li3的内存地址不同,
包含子对象的拷贝, 所以原始对象改变并不会造成深拷贝里面任何子项的改变.

当深拷贝和浅拷贝, 针对的对象全部是不可变数据类型时, 两者效果相同;
当深拷贝和浅拷贝, 针对的对象包含可变数据类型时, 两者才有上述区别;

eg:

>>> import copy
>>> a = [11,22]
>>> b = [33,44]
>>> c = [a,b]
>>> c
[[11, 22], [33, 44]]
>>> d = copy.copy(c)
>>> d
[[11, 22], [33, 44]]
>>> id(c)
139814459865608
>>> id(d)
139814459865288
>>> id(c[0])
139814459768648
>>> id(d[0])
139814459768648
>>> id(a)
139814459768648
>>> e = copy.deepcopy(c)
>>> id(e)
139814459027720
>>> id(c)
139814459865608
>>> id(c[1])
139814459767560
>>> id(b)
139814459767560
>>> id(e[1])
139814458868872
>>> id(d[1])
139814459767560

>>> a = [11,22]
>>> b = [33,44]
>>> c = (a,b)
>>> c
([11, 22], [33, 44])
>>> d = copy.copy(c)
>>> id(c)
139814458868808
>>> id(d)
139814458868808
>>> e = copy.deepcopy(c)
>>> id(e)
139814459842504
>>> id(c[1])
139814458869064
>>> id(e[1])
139814459767560
>>> id(d[1])
139814458869064
>>> id(a)
139814459866568
>>> id(b)
139814458869064
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!