python的深拷贝与浅拷贝,python中的浅拷贝与深拷贝区别

  python的深拷贝与浅拷贝,python中的浅拷贝与深拷贝区别

  第一部分转载自:https://www.cnblogs.com/xueli/p/4952063.html

  1.python的复制,深度复制和浅层复制的区别。在Python中,对象赋值实际上是对对象的引用。当创建一个对象并将其赋给另一个变量时,python并没有复制对象,只是复制了对象的引用。

  通常有三种方法,

  list=[1,2,3,[a , b]]

  (1)直接转让。默认情况下,对象的引用只通过浅层复制传递。如果原来的列表改变了,被赋值的B也会做同样的改变。

  b=列表

  打印b

  [1,2,3,[a , b]]

  list.append(5)

  打印清单;打印b

  [1,2,3,[a , b],5]

  [1,2,3,[a , b],5]

  (2)拷贝浅拷贝,不拷贝子对象,所以原始数据改变,子对象也会改变。

  导入副本

  c=copy.copy(列表)

  打印清单;打印c

  [1,2,3,[a , b]][1, 2, 3, [a, b]]

  list.append(5)

  打印清单;打印c

  [1,2,3,[a , b],5][1, 2, 3, [a, b]]

  名单[3]

  [a , b]

  名单[3]。追加( cccc )

  打印清单;打印c

  [1,2,3,[a , b , cccc],5][1, 2, 3, [a, b, cccc]] 里面的子对象被改变了

  (3)深度副本,在对象中包含了自身对象的副本,所以原对象的变化不会引起深度副本中任何子元素的变化。

  导入副本

  d=copy.deepcopy(列表)

  打印清单;打印d

  [1,2,3,[a , b]][1, 2, 3, [a, b]]始终没有改变

  list.append(5)

  打印清单;打印d

  [1,2,3,[a , b],5][1, 2, 3, [a, b]]始终没有改变

  名单[3]

  [a , b]

  名单[3]。追加( ccccc )

  打印清单;打印d

  [1,2,3,[a , b , ccccc],5][1, 2, 3, [a, b]] 始终没有改变

  2.Python复制的背景和意义,深层复制和浅层复制?不像matlab,比如b=a,它只是用A给B赋值,之后A怎么变,B都不会变。c也是一样。

  你要A变,B就变。引用的概念是在C语言中提出的,相当于一个别名。

  示例:

  int a;int ra=a;//定义引用ra,是对变量A的引用,即别名

  好吧!本文详细解释了轻拷贝和深拷贝的本质原因:重新打开内存进行存储。

  https://www.jianshu.com/p/9ed9b5ce7bb0

  https://baijiahao.baidu.com/s?id=1627356407968660842 wfr=spider for=PC

  本文提出pythond的这种设计可以灵活地防止数据篡改或更改。

  在Python中,有一种关于对象的流行说法。一切都是物体。也就是说,任何构造的数据类型都是对象,不管是数字、字符串、函数,甚至是模块、Python。

  所有Python对象都有三个属性:身份、类型、值

  name= Li j print(type(name))print(id(name))print(name)# output:# type str # 140334394101408 # Li j 可变与不可变对象

  在Python中,根据更新对象的方式,对象可以分为两类:可变对象和不可变对象。

  变量:列表、词典、收藏。所谓可变性,就是可变对象的值是可变的,其身份是不变的。

  不可变对象:数字、字符串、元组。不可变对象是对象的身份和值都不可变。新创建的对象与原始变量名旧对象被丢弃,垃圾回收器会在适当的时机回收这些对象。相关联。

  1= python # string类型不可变print(id(var 1))var 1= Java print(id(var 1))a=[3,4] # list是可变的,print(id(a))a . append(3)print(id(a))#

  引用

  在Python程序中,每个对象都会申请在内存中打开一个空间来保存对象,对象在内存中所在位置的地址称为引用。开发程序时,定义的变量名实际上指的是对象的地址。

  引用实际上是内存中的数字地址号。使用对象时,只要知道对象的地址,就可以操作对象。但是因为这个数字地址在开发过程中不方便使用和记忆,所以用变量名代替对象的数字地址。在Python中,变量就是地址的一种表示形式,并不开辟开辟存储空间。

  就像IP地址一样,访问一个网站的时候,主机其实是由IP地址决定的,不容易记住,所以用域名代替IP地址。当使用域名访问网站时,域名被解析为IP地址以供使用。

  用一个例子说明变量和变量指向的引用是一回事:

  B=18print(id(b))print(id(18))输出:2941331229413312

  浅拷贝:

  print( light copy:)import copy B=[1,2,3,4,5] print (id b:,id (b)) h=copy.copy (b) print (id h ,id(h))print(h)h . append(6b[1]= n #列表元素改变后,新列表保持不变。打印(h)输出:轻型副本:( id b:,14016580510552) (id h ,140165805110480) [1,2,3,4,4]140165805110480][1,2,3,4,5][1,2,3,4,5,6] a=[1,2]l1=[3,4,A] L2=副本。复印(L1)打印(L1)打印(L2)打印(ID (L1))a[0]=11打印(ID(L1))打印(ID (L2))打印(L1)打印(L2)输出:[2]]14062424326197400140624327425704140624324324326197400[3,4,[11,2]][3,4

  可见浅抄相当于只抄一层。当更改时,其值也会更改。

  Python中实现浅层复制的方法有很多,比如复制模块的复制函数、对象的复制函数、工厂方法、切片等。大多数情况下,编写程序时都是使用浅拷贝,除非有特定的需求;浅拷贝的优点:拷贝速度快,占用空间少,拷贝效率高

   深拷贝

  与浅拷贝只拷贝顶级引用不同,深拷贝会一层一层地拷贝,直到拷贝的所有引用都是不可变的引用。

  A=[1,2] L1=[3,4,A]L2=copy . deepcopy(L1)print(L1)print(L2)print(ID(L1))A[0]=11 print(ID(L1))print(ID 4,[1,2]][ID 4,[1,2]][3,4,143984881406727779715720140673014398481406814067140672727277277277774067277272772727777727277777

  为什么Python默认的拷贝方式是浅拷贝?

  时间角度:轻抄耗时少;

  空间角度:轻拷贝耗费内存更少;

  效率:轻拷贝只拷贝顶层数据,一般比深拷贝效率高。

  参考

  https://www.jianshu.com/p/9ed9b5ce7bb0

  https://baijiahao.baidu.com/s?id=1627356407968660842 wfr=spider for=PC

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: