python深拷贝和浅拷贝理解

1. 理解名词

可变对象:列表、字典、集合

不可变对象:数字、字符串、元组

拷贝:复制一个新的对象,新增一块内存空间

引用:不会新增对象,不会开辟新的内存空间,只是多了一个引用

2. 对【不可变对象】进行拷贝,是新增一个对象,即另辟一块内存空间,内存地址不同,一个改变互不影响。 本文总结是对【可变对象】的拷贝。

2.1. 赋值

    listA = [1,2,3,['a','b']]
    listB = listA
    listB.append(5)
    listB[3][0] = 'ax'
    print('ListA值为{0},内存地址id为{1}'.format(listA,id(listA)))
    print('ListB值为{0},内存地址id为{1}'.format(listB,id(listB)))

结果:

ListA值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为37202504
ListB值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为37202504

现象:父对象和子对象全部相同, id也相同

扫描二维码关注公众号,回复: 5150680 查看本文章

总结:1个对象赋值给另一个变量时,没有拷贝对象,只是拷贝对象的一个引用

2.2 浅拷贝

a)切片

listC = listA[:]
listC.append(5)
listC[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA,id(listA)))
print('ListC值为{0},内存地址id为{1}'.format(listC,id(listC)))

结果:

ListA值为[1, 2, 3, ['ax', 'b']],内存地址id为42248776
ListC值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42249608

现象:父对象不同,子对象相同,id不同

总结:切片只是拷贝父对象,包含的子对象只是引用,不拷贝,id不同

b) copy

listD = listA.copy()
listD.append(5)
listD[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA, id(listA)))
print('ListD值为{0},内存地址id为{1}'.format(listD, id(listD)))

结果:

ListA值为[1, 2, 3, ['ax', 'b']],内存地址id为42576456
ListD值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42577288

现象:同切片(现象:父对象不同,子对象相同,id不同)

总结:copy只是拷贝父对象,包含的子对象只是引用,不拷贝,id不同

2.3 深拷贝(注意要导入import copy模块)

listE = copy.deepcopy(listA)
listE.append(5)
listE[3][0] = 'ax'
print('ListA值为{0},内存地址id为{1}'.format(listA, id(listA)))
print('ListE值为{0},内存地址id为{1}'.format(listE, id(listE)))

结果:

ListA值为[1, 2, 3, ['a', 'b']],内存地址id为42510920
ListE值为[1, 2, 3, ['ax', 'b'], 5],内存地址id为42511752

现象:父对象与子对象不同,id不同

总结:深拷贝是对对象及子对象进行拷贝,不是引用。所以互不影响

猜你喜欢

转载自blog.csdn.net/hou_angela/article/details/84971812