1.什么是深浅拷贝?
python中一切皆对象,python中的数字、字符串、元组等,如果存放在了内存中,这部分内存里面的内容是不会改变的,但是也有情况,内存中存放了可变对象,比如说列表和字典,他们的内存空间是可以被修改的。
下面我们定义一个列表:
list=[1,2,3,4,5]
list1=list
list[0]=6
>>>list
[6,2,3,4,5]
>>>list1
[6,2,3,4,5]
如果我们只想改变list,问题就出现了。
赋值操作 list1 = list,是浅拷贝,当list的值改变的时候,list1的值跟着改变。
2.用for和[:]实现浅拷贝
list = [1,2,3,4,5]
list2= [ i for i in list] //list2=list[:]
list2[-1]=0
>>> list
>>> list2
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 0]
上面的例子,用for循环生成新的list2对象或者[:]切片赋值得到的list2,当改变list2的值时,list的值没有跟着改变,这就是深拷贝吗?且继续往下看:
3.
list = [1, 2, 3, [1,2009] ]
list3 = [ i for i in list] //list2=list[:]
list3[-1].append(2009)
>>> list
>>> list3
[1, 2, 3, [1, 2009, 2009]]
[1, 2, 3, [1, 2009, 2009]]
3 和 2难道有矛盾?不。
解释:for循环操作的时候,把list中的每一个对象的引用拷贝,而list中的前3个元素是字符串对象,在python中,字符串对象赋值操作是:变量指向存放字符串的地址,所以看起来好像是深拷贝,实际上还是浅拷贝,若不信,请继续往下看:
4
for i in list:
print id(i)
3630168
3630156
3630144
46784880
for i in list3:
print id(i)
3630168
3630156
3630144
46784880
那么,在pyhton,深拷贝在哪呢?不急,下面就是了
5.
import copy
list= [1, 2, 3, [1,2009] ]
list5 = copy.deepcopy(list)
>>> list
[1, 2, 3, [1, 2009]]
>>> list5
[1, 2, 3, [1, 2009]]
list5[-1].append(2009)
>>> list5
[1, 2, 3, [1, 2009, 2009]]
>>> list
[1, 2, 3, [1, 2009]]
6.总结:
浅拷贝不会拷贝数据中的子对象。
例如:for ,切片浅拷贝,impord copy copy.copy
深拷贝会拷贝数据中的子对象
例如:impord copy.deepcopy