wl413911

python---深拷贝(deep copy)、浅拷贝(shallow copy)

1、对象的比较

  == : 比如a==b ,比较的是a和b指向的值是否相等

  is : 比较的是对象的身份表示是否相等,是否指向同一个内存地址

2、id值

  整数-5 ~ 256 :python内部对整型-5 ~ 256 维持了一个数组,每次创建这样的整型数字时,python返回的都是数组对应的引用

  超过以上范围的引用,就单独开辟一块内存空间了,每次创建,其id值也会不一样

 

浅拷贝: 重新分配一块内存,创建新对象,新对象中的元素是对原对象元素的引用。所以,如果原对象中的元素是可变的,比如是一个列表,其添加或者删除元素等操作会在两个对象中引起共变。


l1 = [[1, 2], (30, 40)]
l2 = list(l1)
l1.append(100)
l1[0].append(3)

l1
[[1, 2, 3], (30, 40), 100]

l2
[[1, 2, 3], (30, 40)]

l1[1] += (50, 60)
l1
[[1, 2, 3], (30, 40, 50, 60), 100]

l2
[[1, 2, 3], (30, 40)]

 

可变序列,可以通过切片完成浅拷贝

 

深拷贝:重新分配一块内存,创建新的对象,新对象中的元素是递归复制原对象中的元素(不是仅复制引用),所以,新对象和原对象没有任何关联,绝对不会引起共变。

    深拷贝的缺陷:如果拷贝的元素对象,存在指向自身的引用,就会陷入死循环

    解决办法:深度拷贝 维护了一个字典,记录已经拷贝过的对象及其id,  在拷贝过程中,如果字典已经存在的对象,会直接返回

 

python提供了相应包实现拷贝:(需要导入import copy)

  浅拷贝  copy.copy()

  深拷贝 copy.deepcopy()

元组:
  t1 = (1, 2, 3)
  t2 = tuple(t1)

  t3 = t1[:]
  t1 == t2 # 返回True ,t1和t2中值相同
  t1 is t2  #返回True  , t1和t2指向了相同的引用

  t1 is t3  # t1和t3指向了相同的引用

 

 

总结:

 

一、赋值:

在 Python 中,对象的赋值就是简单的对象引用,这点和 C++不同


二、浅拷贝(shallow copy):
 
浅拷贝会创建新对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。浅拷贝有三种形式:切片操作、工厂函数、copy 模块中的 copy 函数。

三、深拷贝(deep copy):

深拷贝只有一种形式,copy 模块中的 deepcopy()函数。深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。


四、拷贝的注意点:

1、对于非容器类型,如数字、字符,以及其他的“原子”类型,没有拷贝一说,产生的都是原对象的引用。

比如 l1 = [999,1000,1001]

  l2 = copy.copy(l1)

  l2 is l1  # False

  l2[0] is l1[0]  # True

2、如果元组变量值包含原子类型对象,即使采用了深拷贝,也只能得到浅拷贝。

 

posted on 2020-05-30 12:27  wl413911  阅读(525)  评论(0编辑  收藏  举报