今天电面遇到Python中浅拷贝和深拷贝的区别,平时不经常用当然不知道了,回来就补个课。
先举个非常常见的例子:
1import copy 2 3list1 = [1, 2, 3, ['a', 'b']] 4list2 = list1 5list3 = copy.copy(list1) 6list4 = copy.deepcopy(list1) 7list1.append(5) 8list1[3].append('c') 9 10print 'list1: ', list1 11print 'list2: ', list2 12print 'list3: ', list3 13print 'list4: ', list4 14 15####################################### 16list1: [1, 2, 3, ['a', 'b', 'c'], 5] 17list2: [1, 2, 3, ['a', 'b', 'c'], 5] 18list3: [1, 2, 3, ['a', 'b', 'c']] 19list4: [1, 2, 3, ['a', 'b']] 20########################################
从上面这个例子可以看出,如果浅拷贝一个列表,那么系统会新建一个列表,它的每个元素指向原来那个列表的每个元素(就像C语言里的指针数组),输出的时候会把各个元素指向的元素内容显示出来。所以当list1追加了元素5后,list3并没有显示出来,因为list3中并没有指向这个新元素的元素;但是list1[3]追加了'c',list3也追加了'c',是因为list3中有指向'c'所在列表的元素。
而对于深拷贝来说,无论list1作何改变,list4都不会随之改变,是因为深拷贝是新建一个列表,把原来列表的内容原封不动拷过来,是的新的列表和原来的列表一模一样,这是对象资源的拷贝。
可以再参考下面两个例子。
1.浅拷贝
========
1import copy 2 3class MyClass: 4 def __init__(self, name): 5 self.name = name 6 def __cmp__(self, other): 7 return cmp(self.name, other.name) 8 9a = MyClass('a') 10myList = [a] 11dup_shallow = copy.copy(myList) 12print 'myList: ', myList 13print 'dup_shallow: ', dup_shallow 14print 'dup_shallow is myList: ', (dup_shallow is myList) 15print 'dup_shallow == myList: ', (dup_shallow == myList) 16print 'dup_shallow[0] is myList[0]: ', (dup_shallow[0] is myList[0]) 17print 'dup_shallow[0] == myList[0]', (dup_shallow[0] == myList[0]) 18 19###################################################################### 20myList: [<__main__.MyClass instance at 0x0000000002264408>] 21dup_shallow: [<__main__.MyClass instance at 0x0000000002264408>] 22dup_shallow is myList: False # copy又新建了一个列表,dup_shallow中的元素指向myList中的元素 23dup_shallow == myList: True # 两个列表指向同一块内存地址的内容,则两个列表的内容必定相等 24dup_shallow[0] is myList[0]: True # 两个对象指向的内存地址相同 25dup_shallow[0] == myList[0] True 26######################################################################
2.深拷贝
1import copy 2 3class MyClass: 4 def __init__(self, name): 5 self.name = name 6 def __cmp__(self, other): 7 return cmp(self.name, other.name) 8 9a = MyClass('a') 10myList = [a] 11dup_deep = copy.deepcopy(myList) 12print 'myList: ', myList 13print 'dup_deep: ', dup_deep 14print 'dup_deep is myList: ', (dup_deep is myList) 15print 'dup_deep == myList: ', (dup_deep == myList) 16print 'dup_deep[0] is myList[0]: ', (dup_deep[0] is myList[0]) 17print 'dup_deep[0] == myList[0]', (dup_deep[0] == myList[0]) 18 19################################################################ 20myList: [<__main__.MyClass instance at 0x0000000002264408>] 21dup_deep: [<__main__.MyClass instance at 0x0000000002264308>] 22dup_deep is myList: False 23dup_deep == myList: True # 两个列表虽然指向不同的内存地址,但是内存地址中存储的内容相同 24dup_deep[0] is myList[0]: False # 两个对象的内存地址不同 25dup_deep[0] == myList[0] True 26#################################################################