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