python-浅拷贝(copy)与深拷贝(deepcopy)

这篇具有很好参考价值的文章主要介绍了python-浅拷贝(copy)与深拷贝(deepcopy)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、前言:

二、深拷贝与浅拷贝的异同:

        1.相同点:       

        2.不同点:

        3.形象说明:

        注意:

三、浅拷贝:

 3.1.1浅拷贝示意图:

3.1.2示意图说明

        1.对象与子对象(元素)的关系:

        2.对象:

        3.元素【子对象】:

3.2修改对象:

3.3修改元素(子对象):

3.3.1修改元素(子对象)--可变

3.3.1修改元素(子对象)--不可变

        3.4浅拷贝结论:

四、深拷贝:

4.1深拷贝示意图:

4.2深拷贝:

4.3深拷贝结论:

五、《后续》

5.1修改对象:

        结论2:

5.2修改元素(子对象)

5.2.1修改元素-----可变:

         结论3:

5.2.2修改元素-----不可变:

           结论4:


一、前言:

一、对象与元素、可变与不可变         
        (1)对象:
              对象有存储地址id【就好像某个地址的快递仓库】,对象中的元素都有一个地址id【就像仓库的某某货架】         
        (2)赋值对象指向对象的元素:
               赋值对象或【指向对象】(对象中的元素)有不同的类型【数字,字符串,列表,字典,集合,元组】         
        (3)可变类型与不可变类型:              
                定义:可变就是增删改查之后,对象或元素的存储id不会发生改变,反之就是不可变。   
                1.可变类型:其中【列表,字典,集合】是可变类型                    
                2.不可变类型:【数字,字符串,元组】是不可变数据类型

list1 = [[1, 2], (30, 40),'kkk']
      (4)举例:
         例如以上的列表list1中,有[1, 2]、(30, 40)、'kkk'三个元素,首先列表本身list1是可变的类型,元素[1, 2]是可变的,元素(30, 40)和'kkk'是不可变的

二、深拷贝与浅拷贝的异同:

        1.相同点:       

无论深拷贝还是浅拷贝都会创建一个新对象。即:拷贝出来的对象的id不同。

        2.不同点:

浅拷贝:只拷贝了对象,对象内的元素并不会发生拷贝。
深拷贝:不仅拷贝对象,对象内的元素也会发生拷贝。

        3.形象说明:

深拷贝与浅拷贝形象说明:

首先,有一个数据类型[1,5,6],此时这个数据虽然类型有自己的存储id位置,
但是没有什么意义,因为没有“赋值”给其他的对象,在计算机中“数据没有赋值是没有意义的”。

然后,将数据类型[1,5,6]赋值给一个对象A,也就是A=[1,5,6],此时有了一个对象A,指向了“对象[1,5,6]”,他们是两个不同的id,只是此时是赋值的关系。

然后,深拷贝与浅拷贝都会生成一个新的对象,且与原来的对象是不同的。

然后,浅拷贝---B=copy(A):
     生成了一个新的对象B,没有生成新的“指向对象”,就原来的“指向对象”,
     他们三者的关系是:A----->[1,5,6]<------B
     也就是:浅拷贝得到的【不同对象的“指向对象”是同一个】-----会存在共享部分,也有独立部分

然后,深拷贝--C=deepcopy(A)
     生成了一个新的对象C,也生成了一个新的“指向对象”,
     他们四者间的关系:A----->[1,5,6]
                    C----->[1,5,6]
     也就是:深拷贝得到的【不同对象的“指向对象”是不同的】-----完全独立

        注意:

''' 
如果上面的三者的关系:赋值对象{对象},指向对象,子对象(元素)
没有清楚就不要往下看,不然可能会晕。。。
哈哈哈哈.....
对象可能有子对象[元素],子对象[元素]还有可能有次子对象[元素].......
'''




如A=[8,(9,10),[11,12,(13,14)]]
赋值对象----A
指向对象----[8,(9,10),[11,12,(13,14)]]
一代子对象(元素)----8、(9,10)、[11,12,(13,14)]  三个一代子元素
二代子对象(元素)----9、10、11、12、(13,14)      五个二代子元素  

。。。。。。依次类推

三、浅拷贝:

 3.1.1浅拷贝示意图:

(图示1)

python深度拷贝,数学建模

                因为a,b,c三个子对象(元素)可变类型,所以AB是共享abc的,你变我也变。

                因为’kkk‘和d是不可变类型的子对象(元素),所以是AB不共享kkk‘和d的,你变我不变。

(如下)

python深度拷贝,数学建模

3.1.2示意图说明

        1.对象与子对象(元素)的关系:

                对象可以包含子对象(元素),对象也可以不包含子对象(元素)。

                比如:A1=[[1,2],{'mame':'Marx','age':'23},'kkk',(30,40),{'Aa','33',14,23}]

                           B2=123

                           对象 A1包含了3个子对象和1个元素

                           对象B2没有包含子对象

        2.对象

                不管被复制的对象A不可变的还是可变的,浅拷贝都会生成一个新的对象。

                不管被复制的对象A不可变的还是可变的,如果直接修改对象,那么浅拷贝得到的对象都不会随之改变

                总结:浅拷贝后,如果直接修改对象,双方不会同步改变。

        3.元素【子对象】

               对象有可能会包含子对象【元素】,也就是嵌套比如元组中有【列表/元组】:([1,2],'name','age',(8,9)),列表中有【字典/元组】:[{'age':12},'age',(11,19)]

             子对象【元素】也有可变与不可变的区分。

              修改:如果被修改的对象不可变的,那么两个对象不会同时改变

                         如果被修改的子对象可变的,那么两个对象同时改变

总结:浅拷贝后,如果修改子对象可变的,那么两个对象同时改变。反之就是不会同时改变。

         1.浅拷贝得到的可变子对象共享,不可变子对象独立

         2.改变共享同时变,改变独立对象不互相影响。

3.2修改对象:

         结论1:直接修改对象,那么浅拷贝得到的对象都不会随之改变

实例:A.append(3)

# encoding=utf-8
import copy

A = [[1, 2], (30, 40), 'kkk']
# A=([1,2],8,9)
B = copy.copy(A)
print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2])

print('=============================================')
A.append(3)
print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2]) 

        运行结果:没有同时改变

python深度拷贝,数学建模

3.3修改元素(子对象):

3.3.1修改元素(子对象)--可变

        结论2:修改子对象是可变的,那么两个对象同时改变

        实例:A[0].append(3)

# encoding=utf-8
import copy

A = [[1, 2], (30, 40), 'kkk']
# A=([1,2],8,9)
B = copy.copy(A)
print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2])

print('=============================================')
'''修改可变子对象'''
A[0].append(3)

print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2])

        运行结果:同时改变

python深度拷贝,数学建模

3.3.1修改元素(子对象)--不可变

        结论3:修改子对象是不可变的,那么两个对象不会同时改变

        实例:A[1]+=(50,)

# encoding=utf-8
import copy

A = [[1, 2], (30, 40), 'kkk']
# A=([1,2],8,9)
B = copy.copy(A)
print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2])

print('=============================================')
'''修改不可变子对象'''
A[1]+=(50,)

print(id(A), id(B))
print(A,B)
print(A is B)
print(A[0] is B[0])
print(A[1] is B[1])
print(A[2] is B[2])

运行结果:不同时改变

python深度拷贝,数学建模

        3.4浅拷贝结论:

                结论1:浅拷贝会生成一个新的对象。

                结论2:浅拷贝的两个前后对象会共享可变元素(可变子对象)。是否共享决定了他们是否会同步改变。

                结论3:直接修改对象,另一个不会同步改变。

                结论4:如果修改的子对象是可变的【也就是共享的】,那么二者同步改变

                     如果修改的子对象是不可变的【也就是不共享的】,那么二者不会同步改变

浅拷贝的结论还是下面这张图

python深度拷贝,数学建模

四、深拷贝:

4.1深拷贝示意图:

python深度拷贝,数学建模

4.2深拷贝:

        1.深拷贝后生成了新的一个赋值对象和一个指向对象。
        2.两个赋值对象分别指向了两个不同的指向对象。
        3.两个赋值对象没有改变前的“指向对象的内容是相同”(注意:相同不代表是同一个)的==,但却是不同的两个指向对象 is'''。

        4.深拷贝完全拷贝了父对象及其子对象,两者是完全独立的。

实例如下:

#encoding=UTF-8
from copy import deepcopy

A=[[1, 2], (30, 40),'kkk']

"""1.查看A的存储地址"""
print(id(A))
print(id(A[0]))
print(id(A[1]))
print(id(A[2]))

print('*'*10)

#深拷贝一个对象
B=deepcopy(A)

"""2.查看B的存储地址"""
print(id(B))
print(id(B[0]))
print(id(B[1]))
print(id(B[2]))

"""3.结论1:深拷贝生成的对象完全开辟了新的存储地址,所以有如下判断:"""

print(A is B)       #A并不是B          false
print(A==B)         #A和B是相同的       true
print(A[0] is B[0]) #A[0]并不是B[0]    false
print(A[0]==B[0])   #A[0]和B[0]是相同的 true

深拷贝完全拷贝了父对象及其子对象,两者是完全独立的

4.3深拷贝结论:

                结论:深拷贝完全拷贝了父对象及其子对象,两者是完全独立的,互不再影响。

====================================================================

五、《后续》

从这里开始其实已经是说元素的可变性了,与深拷贝关系不大了,因为深拷贝的两个对象完全独立=====================================================================

5.1修改对象:

        结论2:

               1.深拷贝得到对象与原对象完全独立,两个对象互不再影响。【下面2.3其实是解释】

               2.修改哪个对象,那么只影响被修改的对象,对另外一个不影响。

               3.修改的对象是可变类型,那么被修改的对象的id不会发生变化。

                   修改的对象是不可以变类型,那么被修改的对象的id会发生变化。

实例1:直接在后面添加:A.append(33)

               因为此时的改变对象A本身是列表,是可变类型,所以改变前后A的id没有发生改变

#encoding=UTF-8
from copy import deepcopy

A=[[1, 2], (30, 40),'kkk']

print('==追加前==>')
#深拷贝一个对象
B=deepcopy(A)
print(A,'\n',B)
print(id(A),'\n',id(B))

"""追加一个元素"""
A.append(33)

print('=追加后==>')
print(A,'\n',B)
print(id(A),'\n',id(B))

"""因为此时的改变对象A本身是列表,是可变类型,所以改变前后A的id没有发生改变"""

#小试一下自行判断
print(A is B)
print(A==B)
print(A[0] is B[0])
print(A[0]==B[0])

5.2修改元素(子对象)

5.2.1修改元素-----可变:
         结论3:

               1. 修改对象中的可变元素:

                  被改变对象的元素是可变类型,所以改变前后被修改的元素的id是不变的

实例二:在可变元素后添加:A[0].append(3)

                因为被改变对象的元素A[0]是可变类型,所以改变前后A[0]元素的id是不变的

#encoding=UTF-8
from copy import deepcopy

A=[[1, 2], (30, 40),'kkk']

print('==追加前==>')
#深拷贝一个对象
B=deepcopy(A)
print(A,'\n',B)
print(id(A),'\n',id(B))
print(id(A[0]))

"""可变元素追加一个元素"""
A[0].append(3)

print('=追加后==>')
print(A,'\n',B)
print(id(A),'\n',id(B))
print(id(A[0]))

"""此时因为被改变对象的元素A[0]是可变类型,所以改变前后A[0]元素的id是不变的"""

#小试一下自行判断
print(A is B)
print(A==B)
print(A[0] is B[0])
print(A[0]==B[0])
5.2.2修改元素-----不可变:
           结论4:

                1. 修改对象中的不可变元素:

                  被改变对象的元素是不可变类型,所以改变前后被修改的元素的id是随之改变。

实例三:在不可变元素后添加:A[1]+=(60,)

                因为此时被改变的元素A[1]是不可变的,所以改变前后的元素A[1]的id发生了变化文章来源地址https://www.toymoban.com/news/detail-675104.html

#encoding=UTF-8
from copy import deepcopy

A=[[1, 2], (30, 40),'kkk']

print('==追加前==>')
#深拷贝一个对象
B=deepcopy(A)
print(A,'\n',B)
print(id(A),'\n',id(B))
print(id(A[1]))

"""不可变元素追加一个元素"""
A[1]+=(60,)

print('=追加后==>')
print(A,'\n',B)
print(id(A),'\n',id(B))
print(id(A[1]))

"""因为此时被改变的元素A[1]是不可变的,所以改变前后的元素A[1]的id发生了变化"""

#小试一下自行判断
print(A is B)
print(A==B)
print(A[1] is B[1])
print(A[1]==B[1])

到了这里,关于python-浅拷贝(copy)与深拷贝(deepcopy)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Python:列表的浅拷贝与深拷贝

    相关阅读 Python专栏 https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482         在python语言中,因为其面向对象的特性,在进行列表拷贝时可能会出现一些意想不到的结果,涉及到列表的浅拷贝和深拷贝相关问题,本文将对其进行总结。         首先我们来

    2024年02月09日
    浏览(11)
  • [开发语言][c++][python]:C++与Python中的赋值、浅拷贝与深拷贝

    [开发语言][c++][python]:C++与Python中的赋值、浅拷贝与深拷贝

    写在前面 :Python和C++中的赋值与深浅拷贝,由于其各自语言特性的问题,在概念和实现上稍微有点差异,本文将这C++和Python中的拷贝与赋值放到一起,希望通过对比学习两语言实现上的异同点,加深对概念的理解。 C++中所谓的 浅拷贝 就是由(系统默认的) 拷贝构造函数对

    2024年02月02日
    浏览(14)
  • Python - 拷贝 - 浅拷贝(Shallow Copy)和深拷贝(Deep Copy)

    假设我以这样的方式创建一个 3 x 5 的二维数组: 然后我修改 a [ 2 ] [ 3 ] a[2][3] a [ 2 ] [ 3 ] 的值为 1 1 1 : 结果会发现数组 a a a 中第二维坐标为 3 3 3 的数全部被修改为了 1 1 1 ,而没有发生“第一维坐标为 2 2 2 的数全部被改成了 1 1 1 ” 这就涉及到了Python中的拷贝机制。 Python中

    2023年04月08日
    浏览(7)
  • Java中的浅拷贝与深拷贝

    在Java中,对象的拷贝有两种方式:浅拷贝和深拷贝。它们分别代表了不同的拷贝方式,拷贝出的新对象与原始对象之间存在一定的差异。本文将详细介绍浅拷贝和深拷贝的概念、特点和实现方式,并且通过实例进行解析。  一、浅拷贝  浅拷贝是指在对一个对象进行拷贝时,

    2024年02月14日
    浏览(13)
  • C#中的浅拷贝与深拷贝

    C#中的浅拷贝与深拷贝

    众所周知,C#中有两种类型变量:那就是 值类型 和 引用类型 。对于值类型而言,copy就相当于是全盘复制了,真正的实现了复制,属于 深拷贝 ;而对于引用类型而言,一般的copy只是 浅拷贝 ,只是copy到了引用对象的地址,相当于值传递了一个引用指针, 新的对象通过地址

    2024年02月11日
    浏览(10)
  • 详解js中的浅拷贝与深拷贝

    详解js中的浅拷贝与深拷贝

    1.1 栈(stack)和堆(heap) 栈(stack):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈; 堆(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表 1.2 基本数据类型和引用数据类

    2024年02月08日
    浏览(10)
  • 2023 高教社杯 数学建模国赛(A题)深度剖析|Matlab+python代码双份提供|定日镜场的优化设计|数学建模完整代码+建模过程全解全析

    2023 高教社杯 数学建模国赛(A题)深度剖析|Matlab+python代码双份提供|定日镜场的优化设计|数学建模完整代码+建模过程全解全析

    更新! 当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2021年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题。 希望这些想法对大家的做题有一定的启发和借鉴意义。 构建以新能源为主体的新型电力系

    2024年02月09日
    浏览(40)
  • Pandas数据中的浅拷贝与深拷贝

    Pandas数据中的浅拷贝与深拷贝

    pandas库主要有两种数据结构DataFrames和Series。这些数据结构在内部用索引数组和数据数组表示,索引数组标记数据,数据数组包含实际数据。现在,当我们试图复制这些数据结构(DataFrames和Series)时,我们实际上是复制对象的索引和数据,有两种方法可以做到这一点,即浅复

    2024年02月09日
    浏览(12)
  • 5个常见的前端手写功能:浅拷贝与深拷贝、函数柯里化、数组扁平化、数组去重、手写类型判断函数

    5个常见的前端手写功能:浅拷贝与深拷贝、函数柯里化、数组扁平化、数组去重、手写类型判断函数

    浅拷贝 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。 测试结果: 深拷贝 深拷贝是将

    2024年04月26日
    浏览(16)
  • 【深度学习】因果推断与机器学习的高级实践 | 数学建模

    【深度学习】因果推断与机器学习的高级实践 | 数学建模

    身处人工智能爆发式增长时代的机器学习从业者无疑是幸运的,人工智能如何更好地融入人类生活的方方面面是这个时代要解决的重要问题。滴滴国际化资深算法工程师王聪颖老师发现,很多新人在入行伊始,往往把高大上的模型理论背得滚瓜烂熟,而在真正应用时却摸不清

    2024年02月05日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包