Python Shallow Copy VS. Deep Copy (Python浅拷贝和深拷贝)

今天电面遇到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都不会随之改变,是因为深拷贝是新建一个列表,把原来列表的内容原封不动拷过来,是的新的列表和原来的列表一模一样,这是对象资源的拷贝。

可以再参考下面两个例子。

1.浅拷贝

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
######################################################################


2.深拷贝

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
#################################################################

你可能感兴趣的:(python,copy)