python中的shallow copy 和 deep copy

标签: python  copy
9人阅读 评论(0) 收藏 举报
分类:
  • Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。
  • 1.copy.copy 浅拷贝 只拷贝父对象
  • 2.copy.deepcopy 深拷贝 拷贝父对象及其子对象
  • 3.例子解读:

    >>>x=5
    >>>y=x
    >>>id(x)==id(y)
    True
    
    #刚开始y和x是相同的地址,现在对y赋值
    
    >>>y=10
    >>>id(x)==id(y)
    False
    
    #赋值后y将会有新的地址
    
    
    #若是
    
    >>>x=y#结果就又不一样了

    所以,python默认的是拷贝是对变量的引用,要实现真正的拷贝需要调用copy模块

    列表的拷贝

    >>> colours1 = ["red", "blue"]
    >>> colours2 = colours1
    >>> print(colours1)
    ['red', 'blue']
    >>> print(colours2)
    ['red', 'blue']
    >>> print(id(colours1),id(colours2))
    43444416 43444416
    >>> colours2 = ["rouge", "vert"]
    >>> print(colours1)
    ['red', 'blue']
    >>> print(colours2)
    ['rouge', 'vert']
    >>> print(id(colours1),id(colours2))
    43444416 43444200
    >>> 

    整体改变列表的时候,给引用变量生成了新的地址,再来看改变其中一个元素时,

    >>> colours1 = ["red", "blue"]
    >>> colours2 = colours1
    >>> print(id(colours1),id(colours2))
    14603760 14603760
    >>> colours2[1] = "green"
    >>> print(id(colours1),id(colours2))
    14603760 14603760
    >>> print(colours1)
    ['red', 'green']
    >>> print(colours2)
    ['red', 'green']
    >>> 

    改变引用时,原来变量的值也被改变。可以使用切片运算来进行列表的浅拷贝克服这个问题,

    >>> list1 = ['a','b','c','d']
    >>> list2 = list1[:]
    >>> id(list1)==id(list2)
    False
    >>> list2[1] = 'x'
    >>> print(list2)
    ['a', 'x', 'c', 'd']
    >>> print(list1)
    ['a', 'b', 'c', 'd']
    >>> 

    但是使用切片方法,在列表中包含子列表的时候,新的问题就又出现了,

    >>> lst1 = ['a','b',['ab','ba']]
    >>> lst2 = lst1[:]
    >>> id(lst1)==id(lst1)
    False
    >>> lst2[0] = 'c'
    >>> print(lst1)
    ['a', 'b', ['ab', 'ba']]
    >>> print(lst2)
    ['c', 'b', ['ab', 'ba']]
    
    #但是,若对list2中子列表中值进行修改,list1将还是会受到影响
    
    >>>lst2[2][1]='d'
    >>>print(lst2)
    ['c','b',['ab','d']]
    >>>print(lst1)
    ['a','b',['ab','d']]

    浅拷贝只对父列表进行了拷贝,没有对子列表进行拷贝。如图,

    浅拷贝

    为了解决这个问题,实现列表的完全拷贝,考虑使用copy模块的deepcopy函数,

    >>> from copy import deepcopy
    >>> 
    >>> lst1 = ['a','b',['ab','ba']]
    >>> 
    >>> lst2 = deepcopy(lst1)
    >>> 
    >>> lst1
    ['a', 'b', ['ab', 'ba']]
    >>> lst2
    ['a', 'b', ['ab', 'ba']]
    >>> id(lst1)==id(lst2)
    False
    >>>id(lst1[2][0])==id(lst2[2][0])
    False
    >>> lst2[2][1] = "d"
    >>> lst2[0] = "c"
    >>> print(lst1)
    ['a', 'b', ['ab', 'ba']]
    >>> print(lst2)
    ['c', 'b', ['ab', 'd']]
    >>> 

    其存储示意图如下:

    深拷贝

    测验:

    >>> import copy
    >>> a = [1,2,3,4,['a','b']]  #原始对象
    >>> b = a  #赋值,传对象的引用
    >>> c = copy.copy(a)
    >>> d = copy.deepcopy(a)
    >>> e = a[:]
    >>> a.append(5)
    >>> a[4].append('c')
    >>> print 'a=',a
    a= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    >>> print 'b=',b
    b= [1, 2, 3, 4, ['a', 'b', 'c'], 5] #引用
    >>> print 'c=',c
    c= [1, 2, 3, 4, ['a', 'b', 'c']]  #浅拷贝
    >>> print 'd=',d
    d= [1, 2, 3, 4, ['a', 'b']]      #深拷贝
    >>> print 'e'=,e
    e= [1, 2, 3, 4, ['a', 'b', 'c']]  #浅拷贝

  • refer

[1] https://www.python-course.eu/python3_deep_copy.php

[2] https://stackoverflow.com/questions/17873384/deep-copy-a-list-in-python

查看评论

【Python】第二周Python基础(下)

本周课程主要讲解Python的面向对象编程, 异常处理、模块、MySQL数据库、Python的数据库支持以及图形用户界面等技术,最后我们使用阶段案例开发了一个《飞机大战》的游戏。
  • 2018年03月16日 11:34

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

浅拷贝(shallow copy) copy(x) 创建新的复合对象并通过引用复制x的成员来创建x的浅复制。 更加深层次说,它复制了对象,但对于对象中的元素,依然使用引用。 既然浅拷贝用的是...
  • muzilanlan
  • muzilanlan
  • 2016-01-08 17:57:57
  • 1691

漫谈deepcopy(深拷贝)和shallowcopy(浅拷贝)

浅拷贝:只复制当前的对象,对该对象内部的引用(其他类对象作为自己的元素-也叫对其他对象的引用)不能复制(在堆内存中从新创建空间,内容相同,但地址不同)。 深拷贝:对对象内部的引用均复制,是创建一个新的...
  • u010111016
  • u010111016
  • 2016-06-15 20:23:04
  • 3052

Deep copy(深拷贝)和shallow copy(浅拷贝)的区别

deep copy 和shallow copy 都是用于对象之间的拷贝,简单来说,如果
  • Andrewseu
  • Andrewseu
  • 2014-05-24 18:03:41
  • 2527

C++中ShallowCopy和DeepCopy的区别

C++中ShallowCopy和DeepCopy的区别
  • menjiawan
  • menjiawan
  • 2016-03-02 17:23:01
  • 994

Java中深拷贝(Deep Clone)与浅拷贝(Shallow Clone)

我们先从理论上讨论浅拷贝:         java的类型分为两大类,一类为primitive,如int等8种,另一类为引用类型,如String,Object等等。java的引用类型都是存储在堆上的...
  • snail_rao
  • snail_rao
  • 2012-06-02 21:53:00
  • 5878

shallow copy与deep copy

Java数据类型分为两大类: 基本数据类型与引用数据类型: 基本数据类型: 变量名指向具体的数值 逻辑类型:boolean (默认值:true); 文本类型:char (默认值:'\0',即\u00...
  • u014753393
  • u014753393
  • 2016-04-25 23:45:08
  • 260

再踩Python的Shallow Copy

最近人工智能很火,Python也不可避免地跟着再火一把。 有天在微博上刚好看到这么一段话:@寒冬winter:我来谈两个新标准:写出一个动态规划(最大子段和)再谈算法,写出模拟退火、遗传和神经网三大...
  • jasonblog
  • jasonblog
  • 2017-01-25 12:02:15
  • 1357

Shallow copy & Deep copy

面向对象编程语言都提供了内存中对象的复制能力,Java语言提供了对象的浅拷贝和深拷贝。 浅拷贝(Shallow copy): 复制一个对象时,如果它的一个属性是引用,则复制这个引用,使之指向内存中...
  • Alex_zhuang
  • Alex_zhuang
  • 2012-01-11 11:33:21
  • 561

Shallow Copy与Deep Copy

先做个关于Core Foundation对象复制简单的介绍:   一般来讲,标准的复制,指的是简单的赋值操作的调用,也就是使用 = 操作符来赋值一个变量给另一个变量,比如说: 1 int a ...
  • zhenxi_20
  • zhenxi_20
  • 2014-04-15 16:29:50
  • 415
    个人资料
    持之以恒
    等级:
    访问量: 9589
    积分: 425
    排名: 11万+
    最新评论