python中的深拷贝以及浅拷贝,和java中的概念一样。
浅拷贝:对引用的拷贝。
深拷贝:对对象的资源的拷贝。
首先,对python中的赋值操作我们要有以下认识:
1、赋值是将一个对象的地址赋值给一个变量,让变量指向改地址。
2、修改不可变对象(字符串、元组)需要开辟新的空间。
3、修改可变对象(列表)不需要开辟新的空间。
一般有三种情况:
1、直接赋值(传递对象的引用。原始列表改变,被赋值的一方也会改变)
In[2]: a = [1,2,3]
In[3]: b = a
In[4]: print(b)
[1, 2, 3]
ln[5]: a.append(5)
ln[6]: print(a);print(b)
[1, 2, 3, 5]
[1, 2, 3, 5]
2、copy浅拷贝(没有拷贝子对象,所以原始数据改变,子对象会改变)
In[8]: import copy
In[9]: c = copy.copy(alist)In[10]: print(alist); print(c)
[1, 2, 3, ['a', 'b']]
[1, 2, 3, ['a', 'b']]
In[11]: alist.append( 5)
In[12]: print(alist);print(c)
[1, 2, 3, ['a', 'b'], 5]
[1, 2, 3, ['a', 'b']]
In[13]: alist[ 3 ]
Out[13]: ['a', 'b']
In[14]: alist[3].append( 'ccc')
In[15]: print(alist);print(c)
[1, 2, 3, ['a', 'b', 'ccc'], 5]
[1, 2, 3, ['a', 'b', 'ccc']] #里面的子对象被改变了
3、深拷贝(包含对象里面子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变)
In[16]: import copy
In[17]: d = copy.deepcopy(alist)
In[18]: print(alist);print(d)
[1, 2, 3, ['a', 'b', 'ccc'], 5]
[1, 2, 3, ['a', 'b', 'ccc'], 5] #始终没有改变
In[19]: alist.remove(5)
In[20]: print(alist);print(d)
[1, 2, 3, ['a', 'b', 'ccc']]
[1, 2, 3, ['a', 'b', 'ccc'], 5] #始终没有改变
In[21]: alist[3]
Out[21]: ['a', 'b', 'ccc']
In[22]: alist[3].remove('ccc')
In[23]: print(alist);print(d)
[1, 2, 3, ['a', 'b']]
[1, 2, 3, ['a', 'b', 'ccc'], 5] #始终没有改变
=====================================================
python字典的copy()方法,涉及了浅拷贝和深拷贝,我们来看一个例子:
dict1 = {'user': 'runoob', 'num': [1, 2, 3]} dict2 = dict1 # 浅拷贝: 引用对象 dict3 = dict1.copy() # 浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用 # 修改 data 数据 dict1['user'] = 'root' dict1['num'].remove(1) # 输出结果 print(dict1) print(dict2) print(dict3)
==========================================================================================================
输出结果为:
{'num': [2, 3], 'user': 'root'} {'num': [2, 3], 'user': 'root'} {'num': [2, 3], 'user': 'runoob'}实例中 dict2 其实是 dict1 的引用(别名),所以输出结果都是一致的,dict3 父对象进行了深拷贝,不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改。
更清晰的关于python直接赋值、浅拷贝和深拷贝的内容,请见:http://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html