浅拷贝python
Ⅰ python深拷贝和浅拷贝的区别
浅拷贝是对一个对象父级(外层)的拷贝,并不会拷贝子级(内部),而深拷贝对一个对象是所有层次的拷贝(递归),内部和外部都会被拷贝过来。
使用浅拷贝的时候,分为两种情况。
第一种,如果最外层的数据类型是可变的,比如说列表,字典等,浅拷贝会开启新的地址空间去存放。
Ⅱ python的复制,深拷贝和浅拷贝的区别
在Python中存在深拷贝与浅拷贝的区别,相信有些Python初学者可能就有些疑惑,是指什么意思呢?
1. 赋值其实只是传递对象引用,引用对象id是一样的。
2. 浅拷贝是指拷贝的只是原始对象元素的引用,换句话说,浅拷贝产生的对象本身是新的,但是它的内容不是新的,只是对原对象的一个引用。
3. 深拷贝是指完全拷贝原始对象,而且产生的对象是新的,并且不受其他引用对象的操作影响。
Ⅲ python 为什么有深拷贝浅拷贝
在写Python过程中,经常会遇到对象的拷贝,如果不理解浅拷贝和深拷贝的概念,你的代码就可能出现一些问题。所以,在这里按个人的理解谈谈它们之间的区别。
一、赋值(assignment)
在《Python FAQ1》一文中,对赋值已经讲的很清楚了,关键要理解变量与对象的关系。
12345
>>> a = [1, 2, 3]>>> b = a>>> print(id(a), id(b), sep='\n')
在Python中,用一个变量给另一个变量赋值,其实就是给当前内存中的对象增加一个“标签”而已。
如上例,通过使用内置函数 id() ,可以看出 a 和 b 指向内存中同一个对象。a is b会返回 True 。
二、浅拷贝(shallow )
注意:浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。
所谓“浅拷贝”,是指创建一个新的对象,其内容是原对象中元素的引用。(拷贝组合对象,不拷贝子对象)
常见的浅拷贝有:切片操作、工厂函数、对象的()方法、模块中的函数。
12345678910
>>> a = [1, 2, 3]>>> b = list(a)>>> print(id(a), id(b)) # a和b身份不同140601785066200 140601784764968>>> for x, y in zip(a, b): # 但它们包含的子对象身份相同... print(id(x), id(y))... 140601911441984 140601911442048
从上面可以明显的看出来,a 浅拷贝得到 b,a 和 b 指向内存中不同的 list 对象,但它们的元素却指向相同的 int 对象。这就是浅拷贝!
三、深拷贝(deep )
所谓“深拷贝”,是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。
深拷贝只有一种方式:模块中的deep函数。
1234567891011
>>> import >>> a = [1, 2, 3]>>> b = .deep(a)>>> print(id(a), id(b))140601785065840 140601785066200>>> for x, y in zip(a, b):... print(id(x), id(y))... 140601911441984 140601911442048
看了上面的例子,有人可能会疑惑:
为什么使用了深拷贝,a和b中元素的id还是一样呢?
答:这是因为对于不可变对象,当需要一个新的对象时,python可能会返回已经存在的某个类型和值都一致的对象的引用。而且这种机制并不会影响 a 和 b 的相互独立性,因为当两个元素指向同一个不可变对象时,对其中一个赋值不会影响另外一个。
我们可以用一个包含可变对象的列表来确切地展示“浅拷贝”与“深拷贝”的区别:
>>> import >>> a = [[1, 2],[5, 6], [8, 9]]>>> b = .(a) # 浅拷贝得到b>>> c = .deep(a) # 深拷贝得到c>>> print(id(a), id(b)) # a 和 b 不同139832578518984 139832578335520>>> for x, y in zip(a, b): # a 和 b 的子对象相同... print(id(x), id(y))... 139832578622816 139832578623104>>> print(id(a), id(c)) # a 和 c 不同139832578518984 139832578622456>>> for x, y in zip(a, c): # a 和 c 的子对象也不同... print(id(x), id(y))... 139832578622816 139832578623392
从这个例子中可以清晰地看出浅拷贝与深拷贝地区别。
总结:
1、赋值:简单地拷贝对象的引用,两个对象的id相同。
2、浅拷贝:创建一个新的组合对象,这个新对象与原对象共享内存中的子对象。
3、深拷贝:创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。
浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。
Ⅳ Python中的赋值,浅拷贝和深拷贝的区别
赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,模块的()函数}
深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){模块的deep.deep()函数}
Ⅳ Python3 & 浅拷贝与深拷贝
在Python中对象的赋值(=)其实就是对象的引用。即:当创建一个对象,把它赋值给另一个变量时,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。
Python中对象的拷贝分为:浅拷贝()和深拷贝(deep)。
浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,将原对象在内存中引用地址拷贝过来,然后让新的对象指向这个地址。可以使用“=”或列表自带的()函数(如list.()),或使用模块的()函数。
深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。即把对象复制一遍,并且该对象中引用的其他对象也同时复制,完全得到一个新的一模一样的对象,对新对象里的值进行修改不会影响原有对象,新对象和原对象完全分离开。深拷贝只能使用模块中deep()函数,使用前要导入:from import deep。
Python中对象分为不可变对象 、可变对象。
不可变对象:一旦创建就不可修改的对象,例如:字符串、元组、数字
可变对象:可以修改的对象,例如:列表、字典。
其中Python中的切片可以应用于:列表、元组、字符串,但不能应用于字典。
而深浅拷贝,可应用于序列(列表、元组、字符串),也可应用于字典。
其中不可变对象,不管是深拷贝还是浅拷贝,地址值在拷贝后的值都是一样的。
以下以元组(不可变类型)为例
从上述示例可以看出:
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
所以不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
以下以列表(可变类型)为例
第一种方法:使用=号浅拷贝
输出结果:
第二种方法:使用浅拷贝
输出结果:
第三种方法:使用deep深拷贝
输出结果:
从上述示例可以看出:
=浅拷贝:值相等,地址相等
浅拷贝:值相等,地址不相等
deep深拷贝:值相等,地址不相等
总结:
1,深浅拷贝都是对源对象的复制,占用不同的内存空间。
2,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
3,可变类型的对象,使用=浅拷贝时, 值相等,地址相等,对新对象里的值进行修改同时会影响原有对象;使用浅拷贝时值相等,地址不相等;使用deep深拷贝时值相等,地址不相等。可以看出针对可变类型浅拷贝和deep深拷贝,对新对象里的值进行修改不会影响原有对象。
Ⅵ 什么是深拷贝和浅拷贝
浅拷贝就是指对象复制的时候只复制一层;深拷贝是指复制对象的所有层级。
深拷贝和浅拷贝,主要是对象发生复制的时候,根据复制的层级不同来区分的。很多人在这里经常变量赋值发生混淆。对于JavaScript数组等复杂的数据类型来说,将其赋值给其它变量,其实只是复制了对象的地址给它,两个变量指向的是同一个对象,因此普通的赋值既不是深拷贝也不是浅拷贝。
深拷贝和浅拷贝需要注意的地方就是可变元素的拷贝:
在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的,也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去。
而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的,但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别。
Ⅶ python深拷贝和浅拷贝的区别
1、浅拷贝(shallow )
所谓“浅拷贝”,是指创建一个新的对象,其内容是原对象中元素的引用。(拷贝组合对象,不拷贝子对象)
常见的浅拷贝有:切片操作、工厂函数、对象的()方法、模块中的函数。
2、深拷贝(deep )
所谓“深拷贝”,是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。
深拷贝只有一种方式:模块中的deep函数。
总结:
浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变