Python浅复制与深复制

来源:互联网 发布:福建厦门seo 编辑:程序博客网 时间:2024/06/09 15:10

官方文档http://docs.python.org/2/library/copy.html

我觉得官网上解释的一点都不清楚。stackoverflow上找到不错的说明:地址是http://stackoverflow.com/questions/3975376/understanding-dict-copy-shallow-or-deep




结合下图,通过内存地址分析浅复制。

步骤:

1.a =[1, 2, [3, 4]]

系统首先分配四个内存空间,分别保存1234。然后为对象a开辟一段内存空间,使其指向相应元素的内存空间。

2.b =list(a)

浅复制。系统为对象b开辟一段内存空间,使其指向相应元素的内存空间。



a/b对象初始化完成后,开始进行修改处理。

1.a[0]= 0



分析:

其实系统会先为0分配一个内存空间,同之前的1234。然后,改变了a[0]的指向,使其指向元素0。因此,不影响b[0]


2.a[2][0]= 5



分析:

在对象a中,a[2]指向的是另一块内存空间X,这块内存空间指向对象3/4两个内存空间。

a[2][0]便是指向内存空间X中的第一个元素的地址,指向对象3

此时,a[2][0]= 5语句的作用:内存空间X的地址不变,但是它将X中第一个位置的指针指向了元素5id(a[2][0])发现地址已经变化。

又因为b[2]a[2]所指向的是同一个内存空间X,所以当X内部发生变化时,会影响对象ab



测试文件test_for_copy.py()

#!/usr/bin/env pythonimport copya = [1, 2, [3, 4]]#a = {'alice':1, 'bruce':2, 'christ':{'addr':'1009', 'phone':1234}}b = ac = copy.copy(a)d = copy.deepcopy(a)#a[0] = 10print a #print bprint c#print dprint id(a[2][0]) #1print id(c[2][0]) #2print id(a) == id(c)print id(a[0]) == id(c[0])print id(a[2]) == id(c[2])print id(a[2][0]) == id(c[2][0])a[2][0] = 10 #test for listprint id(a[2][0]) #3print id(c[2][0]) #4#1/2 and 3/4 are the same, but 1/3 and 2/4 are different.


结合下图,通过内存地址分析深复制。




深复制创建一个新对象,并递归复制所有子对象。

ps:当为b[2]创建新对象后,发现它是一个列表,里面还是子元素,则为该列表创建新对象,继续递归下去。因此最后对象a中所有的内容,都有一份新的拷贝赋给对象b。即ba没有任何关系了。


验证:

1.a[2][0]= 5




原创粉丝点击