美文网首页
Python中的赋值、深浅拷贝

Python中的赋值、深浅拷贝

作者: Ghibli_Someday | 来源:发表于2018-10-16 00:51 被阅读13次

    拷贝对象的意义在于:如果需要在不更改源数据的情况下,修改数据,此时需要一个拷贝对象

    python提供copy来完成这样的拷贝

    1、赋值

    lst = [1, ['a', 'b']]
    L = lst
    lst.insert(1, 2)
    lst[2].append('c')
    print('lst:', lst, 'id:', id(lst))
    print('L:', L, 'id:', id(L))
    print('lst中元素的value和id')
    for i in lst:
        print('value:', i, 'id:', id(i))
    print('L中元素的value和id')
    for i in L:
        print('value:', i, 'id:', id(i))
    

    结果为:

    lst: [1, 2, ['a', 'b', 'c']] id: 38425416
    L: [1, 2, ['a', 'b', 'c']] id: 38425416
    lst中元素的value和id
    value: 1 id: 1588096032
    value: 2 id: 1588096064
    value: ['a', 'b', 'c'] id: 38425224
    L中元素的value和id
    value: 1 id: 1588096032
    value: 2 id: 1588096064
    value: ['a', 'b', 'c'] id: 38425224
    

    从上面的结果得知,赋值并没有为 L 建立新的内存空间,lst 的 value 和 id 以及其元素的 value 和 id 都是与 L 相同的,说明只是将 L 指向 lst,新的对象没有被创建,你可以理解为一个人有2个名字,虽然不同,但都是同一个人

    2、浅拷贝

    import copy
    lst = [1, ['a', 'b']]
    L = copy.copy(lst)
    print('数据操作前lst和L的id值')
    print('id(lst):', id(lst), 'id(L):', id(L))
    lst.insert(1, 2)
    lst[2].append('c')
    print('操作后:')
    print('lst:', lst, 'id:', id(lst))
    print('L:', L, 'id:', id(L))
    print('lst中元素的value和id')
    for i in lst:
        print('value:', i, 'id:', id(i))
    print('L中元素的value和id')
    for i in L:
        print('value:', i, 'id:', id(i))
    

    结果:

    数据操作前lst和L的id值
    id(lst): 38028168 id(L): 38029448
    操作后:
    lst: [1, 2, ['a', 'b', 'c']] id: 38028168
    L: [1, ['a', 'b', 'c']] id: 38029448
    lst中元素的value和id
    value: 1 id: 1589996576
    value: 2 id: 1589996608
    value: ['a', 'b', 'c'] id: 38027976
    L中元素的value和id
    value: 1 id: 1589996576
    value: ['a', 'b', 'c'] id: 38027976
    

    从结果得知,L 的 id 与 lst 的 id 在数据操作前就已经不同了,说明浅拷贝为拷贝对象 new 了一个新对象,继续观察可以发现不同的结果有,lst新增数据 2,而 L并没有相应增加(因为它们属于两个不同的对象了)

    3、深拷贝

    import copy
    lst = [1, ['a', 'b']]
    L = copy.deepcopy(lst)
    print('数据操作前lst和L的id值')
    print('id(lst):', id(lst), 'id(L):', id(L))
    lst.insert(1, 2)
    lst[2].append('c')
    print('操作后:')
    print('lst:', lst, 'id:', id(lst))
    print('L:', L, 'id:', id(L))
    print('lst中元素的value和id')
    for i in lst:
        print('value:', i, 'id:', id(i))
    print('L中元素的value和id')
    for i in L:
        print('value:', i, 'id:', id(i))
    

    结果:

    数据操作前lst和L的id值
    id(lst): 34096008 id(L): 34097288
    操作后:
    lst: [1, 2, ['a', 'b', 'c']] id: 34096008
    L: [1, ['a', 'b']] id: 34097288
    lst中元素的value和id
    value: 1 id: 1588096032
    value: 2 id: 1588096064
    value: ['a', 'b', 'c'] id: 34095816
    L中元素的value和id
    value: 1 id: 1588096032
    value: ['a', 'b'] id: 34097224
    

    我们对比浅拷贝来看,深拷贝也是新建了一个内存地址,不可变对象 1 还是 1,但可变对象['a', 'b']也为它新增了一个内存地址,浅拷贝中是没有的,所以浅拷贝中,list数据的改变是同步的,而深拷贝是不一样的结果。

    结论:

    • 直接赋值并没有新建对象,只是多了一个引用名
    • 深、浅拷贝都是对源对象的复制,占用不同的内存空间。区别在于浅拷贝对可变对象的是完全复制,深拷贝是新建内存空间,只复制其值

    相关文章

      网友评论

          本文标题:Python中的赋值、深浅拷贝

          本文链接:https://www.haomeiwen.com/subject/ziqczftx.html