可以看到问题就出来了,即对一个小列表进行修改,会影响到其它的小列表。我们先抛开所谓的浅拷贝,去思考这个问题本身:有可能不会影响其它小列表吗?肯定没有可能的,因为三个小列表的id都一样,三个小列表里的元素的id也一样,即其实这三个小列表是完全指向同一个对象的,因此,无论修改哪一个,肯定都会影响其它小列表的。
这就是所谓浅拷贝出现的问题。
--------------------------------------------------------------------------------
3.第三个例子:使用深拷贝来解决第二个例子出现的问题
>>> person = ['name', ['age', 20]]
>>> linuxidc = person[:]
>>> from copy import deepcopy as dcp
>>> cl = dcp(person)
>>> person, linuxidc, cl
(['name', ['age', 20]], ['name', ['age', 20]], ['name', ['age', 20]])
>>> [id(x) for x in person, linuxidc, cl]
[140205544995944, 140205544893688, 140205544875144]
# 查看大列表的元素id值
>>> [id(x) for x in person]
[140205546176112, 140205544996520]
>>> [id(x) for x in linuxidc]
[140205546176112, 140205544996520]
>>> [id(x) for x in cl]
[140205546176112, 140205544571320]
# 查看小列表的元素id值
>>> [id(x) for x in person[1]]
[140205545021232, 32419728]
>>> [id(x) for x in linuxidc[1]]
[140205545021232, 32419728]
>>> [id(x) for x in cl[1]]
[140205545021232, 32419728]
可以看到虽然是进行了深拷贝,但发现跟前面的其实并没有什么不同,下面我们再来修改其中一个小列表:
>>> linuxidc[1][1] = 22
>>> person, linuxidc, cl
(['name', ['age', 22]], ['name', ['age', 22]], ['name', ['age', 20]])
# 查看大列表的元素id值
>>> [id(x) for x in person]
[140205546176112, 140205544996520]
>>> [id(x) for x in linuxidc]
[140205546176112, 140205544996520]
>>> [id(x) for x in cl]
[140205546176112, 140205544571320]
# 查看小列表的元素id值
>>> [id(x) for x in person[1]]
[140205545021232, 32419680]
>>> [id(x) for x in linuxidc[1]]
[140205545021232, 32419680]
>>> [id(x) for x in cl[1]]
[140205545021232, 32419728]
此时可以看到,cl的小列表的第二个元素的id跟原来是一样的,但是linuxidc和person的小列表元素的id发生了改变,同时值也是我们修改的那样。那是因为linuxidc是person的浅拷贝,但是cl是person的深拷贝。
这就是所谓的深拷贝。
--------------------------------------------------------------------------------
4.第四个例子:检验
其实只要理解了上面三个例子(这意味着对Python对象本身和序列类型本身也有比较深刻的理解),所以的浅拷贝和深拷贝也不是什么问题了。
至于是否明白,可以参考下面这个例子:
>>> person = ['name', ('hobby', [1, 2])]
>>> linuxidc = person[:]
>>> from copy import deepcopy as dcp
>>> cl = dcp(person)
>>>
>>> linuxidc[0] = 'xpleaf'
>>> cl[0] = 'cl'
>>> person, linuxidc, cl
(['name', ('hobby', [1, 2])], ['linuxidc', ('hobby', [1, 2])], ['cl', ('hobby', [1, 2])])
>>>
>>> linuxidc[1][1][0] = 'clyyh'
>>> person, linuxidc, cl
(['name', ('hobby', ['clyyh', 2])], ['linuxidc', ('hobby', ['clyyh', 2])], ['cl', ('hobby', [1, 2])])
如果对这个例子的输出觉得完全没有问题的,那么也就OK了!
当然,肯定还有遗漏的地方,还望指出。
下面关于Python的文章您也可能喜欢,不妨看看:
Ubuntu 14.04 下安装使用Python rq模块
CentOS上源码安装Python3.4
《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版]