转自文章 http://iaman.actor/blog/2016/04/17/copy-in-python
最近遇到了有关Python中的copy与deepcopy问题,之前再Java里面好像也遇到了深浅复制的问题,但是Python中的深浅复制还不是很熟,就简单了解了一下它们2个的差别,可以供大家参考,不对的地方欢迎大家批评指正。
代码说明:当改变 复杂子对象中的元素时,浅复制值发生了变化; 当改变的值不是复杂子对象,浅复制的值没有发生变化。因为 浅复制 ,复杂子对象的保存方式是 作为 引用 方式存储的,所以修改 浅复制的值 和原来的值都可以 改变 复杂子对象的值。
对象的浅复制,深复制问题,在面试中经常被问到,不管是 C++, Java, 还是 Python,一般都会问这个问题。今天以Python为例来说明浅复制问题。
在实际开发过程中,我们会遇到需要将相关数据关联起来的情况,例如,处理学生的学号、姓名、年龄、成绩等信息。另外,还会遇到需要将一些能够确定的不同对象看成一个整体的情况。Python提供了字典和集合这两种数据结构来解决上述问题。这里介绍一下python字典的更新复制相关知识。
在前文已经看到过了可以使用list函数去复制一个列表,这个就是浅复制,浅复制会构建一个新的对象,并且维护之前对象(子对象)的引用,而深复制则是将之前的子对象通过递归的方式也拷贝出来。从例子中学习吧。 先看看浅复制:
跟其他编程语言不同,Python的变量不是盒子,不会存储数据,它们只是引用,就像标签一样,贴在对象上面。
""" a = [1, 2] b = a #赋值 c = a.copy() #浅复制 a.append(3) print(b) #父对象改变 print(c) #父对象不变 ''' [1, 2, 3] [1, 2] ''' """
我们都知道,Python 中有两种可变的数据类型:list 和 dict。这两种数据类型对应的实例也有很多方法可以对自身进行修改,需要注意的是,这里调用修改相关的方法的时候不是返回修改后的实例,而是就地修改,也就是原地修改。我们有些时候不希望原来的被修改,因此,复制它们的实例就显得非常重要。
在OC中,因为采用内存计数的方式管理内存,所以浅复制时会对同一个内容计数加一,深复制则不会。
下午在用python将Linux的conf配置文件转化成字典dict时遇到了一个奇怪的问题,原先conf配置文件中没有注释行(以#开头的行),后来为了避免这种情况,添加了一个对以#开头的行删除的操作。 实践结果颠覆了已有的认知,直接上代码示例。 代码片段1
1.直接赋值 y = x 传递原始对象的引用,而不是一个副本,即y与x指向同一个对象 2.浅复制(拷贝) y = x.copy() 浅复制(拷贝)产生的对象是新的,但是它的子对象只是对原
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. 给定一个链表,此链表有点特殊,里面有一个不大一样的属性节点,它指向链表中的另一个随机节点或不指向任何节点。要求返回这个链表的深拷贝。
摘要: 程序中常常需要复制一个对象, 按思路应该是这样的a = [1, 2, 3]b = a# [1, 2, 3]print b 已经复制好了,但是现在得改变一下第一个元素的值把它改成5b[0] = 5 # [5, 2, 3]print b # [5, 2, 3]print a 我改变了b的第一个元素的值,但是a的值也改变了,这是因为python中的=是引用...
文章使用markdown写的,编辑的时候行间距还可以,显示的时候行间距好小,我也没办法。
浅复制:在C#中调用 MemberwiseClone() 方法即为浅复制。如果字段是值类型的,则对字段执行逐位复制,如果字段是引用类型的,则复制对象的引用,而不复制对象,因此:原始对象和其副本引用同一个对象!
变量定义:一段存放在内存特定区域的空间,在python中变量名没有类型,引用的对象有类型之分;
1.字符串拼接 2.格式化输出 3.神复制和浅复制 1.字符串拼接 例: a='hello', b='python',c='!' 将a,b,c中的字符串连成一句话。 1.用+号 a+b+c 2.格式化字符串 % '%s %s %s' % (a,b,c) 3.''.join()方法,注意括号是要连接的(可以是列表,元祖) ' '.join([a,b,c]) #''里面是连接后各个字符串的字符 4. .format方式 '{}{}{}'.format(a,b,c) #{}里面可以填入与后面相对应的符号
元组的不可变性 其实是指 tuple 数据结构的 物理内容(即保存的引用)不可变,与引用的对象无关
关于Java中的深复制、浅复制,网上也有很多资料解释,这里整理出来加入一些自己的想法。
id(x)函数 id()函数可以查看一个变量在内存中的地址 变量赋值给变量-拷贝引用 对于以下代码 >>> import copy >>> a=[1,2,3] >>> b=a >>> id(a) """ 4382960392 """ >>> id(b) """ 4382960392 """ >>> id(a)==id(b) #赋值后,两者的id相同,为true。 True >>> b[0]=222222 #此时,改变b的第一个值,也会导致a值改变。 >>> print(a,b) [222222,
#无重复,可变–>元素的去重 #无序、唯一、可变。集合中的元素需要可哈希的,元素不可以是可变对象。 #内置函数len(),max(),min(),tuple(),enumerate()
本文由腾讯云+社区自动同步,原文地址 https://stackoverflow.club/python-deep-shallow-copy/
# Auther: Aaron Fan names = ["aaron", "alex", "james", "meihengfan"] #复制一份列表 #浅复制 (注意,这只是一个浅复制,只能复制第一层列表里面的东西,如果列表里面还有一层列表,那么那一层的列表只是把物理地址指向过去了,但是并没有复制过来) #在day2第9个视频,有详细讲这个浅复制的作用,这里不再详细注释 person = ["name", ["saving", 100]] ''' 浅复制的方法有3种: p1 = person.
原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中,复制对象是通过clone()实现的,先创建一个原型类:
列表对象的copy()方法返回列表的浅复制。所谓浅复制,是指生产一个新的列表,并且把原列表中所有元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样的不可变类型,一般是没有问题的。但是,如果原列表中包含列表之类的可变数据类型,由于浅复制时只是把子列表的引用复制到新列表中,这样修改任何一个都会影响另外一个。例如: >>> x = [1, 2, [3, 4]] #原列表中包含子列表 >>> y = x.copy() #浅复制 >>> x [1, 2, [3, 4]] >>>
本来今天不打算用别人的故事了,但是吧,技术这东西,枯燥无味,如果我们连学个东西干嘛用都不知道,那学来干嘛?所以我觉得,这个入门应用场景是很重要的。
拷贝就是复制,创建副本。假设有对象A,A有属性t1,t2。那么,我通过拷贝A,得到B,B应该也有属性t1,t2,且A、B两个对象的每个属性,都应该是相同的。
“浅复制”:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。也就是说,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
很多人在学习python3的时候,在字典部分copy和deepcopy感到很困惑,现在针对这两个方法进行区分,即一种是浅复制(copy),一种是深度复制(deepcopy)。
原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。
本文主要介绍Python中的Iterable与Iterator,其中Iterable为可迭代对象,Iterator为迭代器对象。
输入一个正整数,输出它的所有质数因子(如180的质数因子为 2、2、3、3、5。
首先明确一点,System.arraycopy 操作的是数组,效果是深复制。 是不是觉得怎么和你印象的中不一样? 重点来了,对于对象数组,例如: User[],这种数组,有一个注意点,这个点就是:对于数组内的对象是浅拷贝。
在SystemVerilog面向对象编程中,只有在类句柄执行new()函数之后才会创建对象,分配内存空间。
请写出一段 Python 代码实现分组一个 list 里面的元素,比如 [1,2,3,…100]变成 [[1,2,3],[4,5,6]…]
原理: 通过copy方法可以创建可变对象或不可变对象的不可变副本,对于不可变副本,其对象的值不可以改变。 通过mutableCopy方法可以创建可变对象或不可变对象的可变副本,对于可变副本其对象是可变的。 复制分为浅复制和深复制两种:浅复制只是复制对象的引用,并没有复制对象的具体内容。深复制则创建了要复制对象的具体内容,并返回对象副本的引用。 对于复制Foundation中的对象,默认并不是深复制,例如copy NSMutableArray对象是浅复制,只是对其引用进行复制;而copy N
本章的内容有点枯燥,但是这些话题却是解决Python程序中很多不易察觉的bug的关键。
有关浅复制与深复制的定义为:对类进行复制的时候按位复制,即把一个对象各数据成员的值原样复制到目标对象中。当类中涉及到指针类型数据成员的时候,往往就会产生指针悬挂问题。
原型模式(Prototype) 原型模式(Prototype) 意图:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。 应用:Java/C#中的Clonable和IClonable接口
我们把前面创建的UserDto对象引用复制给userDto了,然后又对对象中的两个属性进行重新赋值,userDto1也会随着赋值的。这就是所谓的浅克隆(浅复制)。
深复制和浅复制也称为深拷贝和浅拷贝。简单的说就是创建一个和当前对象一模一样的对象。在日常编码的过程中使用的几率并不多,但在面试中却会被经常问到。
python使用5种数字类型:布尔型、整型、长整型、浮点型和复数,所有数字类型均为不可变对象。
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,
在这个示例代码中,我们定义了一个原型接口 Prototype 和一个具体的学生类 Student,该类实现了原型接口并重写了 clone() 方法。在客户端代码中,我们创建了一个原型对象 stu1,并通过克隆原型对象来生成一个新的学生对象 stu2,然后修改 stu2 对象的属性并打印结果。由于 stu1 和 stu2 对象是互相独立的,因此修改 stu2 的属性不会影响 stu1 对象的属性。
replaceWith()与replaceAll()都会替换所有匹配的元素为指定元素。
由结果看,PHP中array_push方法和array_object的结果也不同。
在 python 中赋值语句总是建立对象的引用值,而不是复制对象。因此,python 变量更像是指针,而不是数据存储区域, 这点和大多数 OO 语言类似吧,比如 C++、java 等 ~ 1、先来看个
领取专属 10元无门槛券
手把手带您无忧上云