当前位置:首页 » 编程语言 » python深拷贝

python深拷贝

发布时间: 2024-07-01 10:48:25

‘壹’ python字典操作问题

应为在python中dict是可变对象。用dic1赋值给dic3后,并没有创建一个新的对象,dic3和dic1指向同一个对象。通过dic3改变其内容,就如同通过dic1改变对象内容一样。

具体的内容你可以看看深拷贝和浅拷贝

import
defcom_weight(dic1,dic2):
dic3=.deep(dic1)#深拷贝,,,,
foriindic1.keys():
forjindic1[i].keys():
dic3[i][j]=dic1[i][j]-dic2[i][j]

printdic3

if__name__=='__main__':

dic1={1:{1:142264,2:142315},2:{3:142111},3:{3:142723}}
dic2={1:{1:142263,2:142312},2:{3:142110},3:{3:142722}}

print'__________________'
printdic1
printdic2
print'*******************'
com_weight(dic1,dic2)
print'~~~~~~~~~~~~~~~~~~~~~~~~'
printdic1
printdic2

‘贰’ 什么是深拷贝和浅拷贝

浅拷贝就是指对象复制的时候只复制一层;深拷贝是指复制对象的所有层级。

深拷贝和浅拷贝,主要是对象发生复制的时候,根据复制的层级不同来区分的。很多人在这里经常变量赋值发生混淆。对于JavaScript数组等复杂的数据类型来说,将其赋值给其它变量,其实只是复制了对象的地址给它,两个变量指向的是同一个对象,因此普通的赋值既不是深拷贝也不是浅拷贝。

深拷贝和浅拷贝需要注意的地方就是可变元素的拷贝:

在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的,也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去。

而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的,但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别。

‘叁’ 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,将一个列表的数据复制到另一个列表中。

#coding=utf-8
import
list=[1,2,3]

#普通赋值(引用)
list_a=list
#切片赋值(引用)
list_b=list[:]
#浅拷贝
list_c=list.()
list_d=.(list)#需要导入包
#深拷贝
list_e=.deep(list)#需要导入包

‘伍’ python深拷贝和浅拷贝的区别

1、浅拷贝(shallow )

所谓“浅拷贝”,是指创建一个新的对象,其内容是原对象中元素的引用。(拷贝组合对象,不拷贝子对象)

常见的浅拷贝有:切片操作、工厂函数、对象的()方法、模块中的函数。

2、深拷贝(deep )

所谓“深拷贝”,是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。

深拷贝只有一种方式:模块中的deep函数。

总结:

浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变

深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变

‘陆’ python如何赋值后让变量保持不变

python中字典和列表都是可变类型,直接通过赋值的方式(也就是浅拷贝),只是创建了新的对象,但实际还是引用了同一个地址,要想修改d而不对dic产生影响,使用深拷贝的方式:

import

d = .deep(dic)

‘柒’ python浜岀淮鍒楄〃姹傚府蹇

鍦≒ython涓锛屼娇鐢╟opy()鏂规硶澶嶅埗涓涓鍒楄〃镞讹纴濡傛灉鍒楄〃镄勫厓绱犳槸鍙鍙樼被鍨嬬殑锛埚傚垪琛锛夛纴闾d箞鐢熸垚镄勬柊鍒楄〃涓镄勮繖浜涘彲鍙桦厓绱犲疄闄呬笂鏄铡熷垪琛ㄤ腑鍏幂礌镄勫紩鐢锛屼篃灏辨槸璇达纴瀹冧滑鎸囧悜镄勬槸钖屼竴涓瀵硅薄銆傚洜姝わ纴鍦ㄤ慨鏀硅繖浜涘厓绱犳椂锛屼笉绠℃槸阃氲繃铡熷垪琛ㄨ缮鏄阃氲繃澶嶅埗镄勬柊鍒楄〃杩涜岋纴閮戒细褰卞搷鍒板师鍒楄〃涓镄勫厓绱犮
濡傛灉瑕佸嶅埗涓涓浜岀淮鍒楄〃锛屽苟纭淇濅慨鏀规柊鍒楄〃涓镄勫厓绱犱笉浼氩奖鍝嶅埌铡熷垪琛锛屽彲浠ヤ娇鐢ㄦ繁𨰾疯礉锛坉eep锛夋柟娉曘傛繁𨰾疯礉浼氩嶅埗镓链夊厓绱狅纴鍖呮嫭宓屽楃殑鍒楄〃鍜屽叾浠栧彲鍙樼被鍨嬬殑鍏幂礌锛岀敓鎴愪竴涓鍏ㄦ柊镄勫硅薄锛屼笌铡熷硅薄瀹屽叏镫绔嬨
绀轰緥浠g爜濡备笅锛
import
# 铡熶簩缁村垪琛
a = [[1, 2], [3, 4]]
# 娣辨嫹璐
b = .deep(a)
# 淇鏀规柊鍒楄〃涓镄勫厓绱
b[0][0] = 5
# 杈揿嚭铡熷垪琛ㄥ拰鏂板垪琛
print(a) # [[1, 2], [3, 4]]
print(b) # [[5, 2], [3, 4]]
鍙浠ョ湅鍒帮纴铏界劧淇鏀逛简鏂板垪琛ㄤ腑镄勫厓绱狅纴浣嗗师鍒楄〃骞舵病链夊弹鍒板奖鍝嶏纴杩欐槸锲犱负娣辨嫹璐濈敓鎴愪简涓涓鍏ㄦ柊镄勪簩缁村垪琛ㄥ硅薄锛屼笌铡熷硅薄瀹屽叏镫绔嬨

热点内容
c语言乘积函数 发布:2024-11-26 17:43:23 浏览:186
unix与linux的关系 发布:2024-11-26 17:38:37 浏览:463
中恒牌密码锁初始管理密码是多少 发布:2024-11-26 17:34:54 浏览:295
ios手机怎么玩安卓游戏 发布:2024-11-26 17:08:23 浏览:395
sql记录执行 发布:2024-11-26 17:08:15 浏览:8
deb反编译 发布:2024-11-26 17:04:12 浏览:140
ftp站点如何设置 发布:2024-11-26 16:54:48 浏览:849
预设存储器 发布:2024-11-26 16:47:38 浏览:14
如何打开云服务器的窗口 发布:2024-11-26 16:42:37 浏览:844
怎么自学编程入门 发布:2024-11-26 16:40:58 浏览:760