python的浅拷贝与深拷贝

初用python 写起来跟js很像,比较爽,不过很快就遇到了坑

l = []d = {'num': 0, 'sqrt': 0}for x in [1, 2, 3]:    d['num'] = x     d['sqrt'] = x*x     l.append(d)print l

注意这里l append进去的是d的引用,而不是另一个独一无二的东西。因此结果应该是

[{'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}]

l内部有三个d的引用。每当我们修改d,那么d的引用会被相应修改。

而我们想得到的是,从1到3的平方,那么可以采用浅拷贝

l = []d = {'num': 0, 'sqrt': 0}for x in [1, 2, 3]:    d['num'] = x     d['sqrt'] = x*x     l.append(d.copy())print l

这里浅拷贝与深拷贝有什么区别呢?举个栗子(采用copy模块)

m = [1, [2, 2], [3, 3]]n = copy.copy(m)n[1].append(2)print m, n//[1, [2, 2, 2], [3, 3]] [1, 0, [3, 3]]//其实修改的m[1]n[1] = 0print m, n//[1, [2, 2, 2], [3, 3]] [1, 0, [3, 3]]//覆盖了n[1]引用的m[1]n[2].append(3)print m, n//[1, [2, 2, 2], [3, 3, 3]] [1, 0, [3, 3, 3]]//修改m[2]m[1].pop()print m, n//[1, [2, 2], [3, 3, 3]] [1, 0, [3, 3, 3]]//修改m[1],对n没影响了m[2].pop()print m, n//[1, [2, 2], [3, 3]] [1, 0, [3, 3]]//修改m[2],相应的n[2]也被修改。

我们利用浅拷贝拷贝了m后,对象的属性还是引用原来的。因此如果利用下标,修改下标引用的那个子对象,修改的还是原来的对象。

而当我们把n[1]子对象覆盖后,n[1]就跟m没啥关系了。

再看深拷贝

a = [1, 2, 3, 4, ['a', 'b']] #原始对象b = a #赋值,传对象的引用c = copy.copy(a) #对象拷贝,浅拷贝d = copy.deepcopy(a) #对象拷贝,深拷贝a.append(5) #修改对象aa[4].append('c') #修改对象a中的['a', 'b']数组对象print 'a = ', aprint 'b = ', bprint 'c = ', cprint 'd = ', d
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]c =  [1, 2, 3, 4, ['a', 'b', 'c']]d =  [1, 2, 3, 4, ['a', 'b']]

深拷贝把子对象也拷贝了,因此修改原对象的子对象,会影响浅拷贝的子对象,而不会影响深拷贝。

总结来讲?copy拷贝一个对象,但是对象的属性还是引用原来的,deepcopy拷贝一个对象,把对象里面的属性也做了拷贝,deepcopy之后完全是另一个对象了。

参考?http://luchanghong.com/python/2012/09/21/the-differences-between-copy-and-deepcopy-in-python.html

python的浅拷贝与深拷贝

相关文章:

你感兴趣的文章:

标签云: