• 深拷贝,浅拷贝与赋值符号的不同


    深浅拷贝和赋值的区别

    lis1 = [1, 2, 3, 4, ["xxx", "ahaha"]]   # 以一个列表lis1为例
    lis2 = lis1                 # lis2用来显示赋值的效果
    lis3 = lis1.copy()          # lis3用来显示浅拷贝的效果
    print(id(lis1), id(lis2), id(lis3))
    # 2405339158472 2405339158472 2405339158600             
    # 可以看到lis1和2的内存地址相同,lis3不同
    # 得到结论:赋值后lis1与lis2等效,指向同一个数据
    print(id(lis1[0]), id(lis1[1]), id(lis1[2]), id(lis1[4]))
    print(id(lis2[0]), id(lis2[1]), id(lis2[2]), id(lis2[4]))
    print(id(lis3[0]), id(lis3[1]), id(lis3[2]), id(lis3[4]))
    # 1444529840 1444529872 1444529904 2405339158728
    # 可以看到未进行数据修改时,第一层的内存地址都相同
    # 1444529840 1444529872 1444529904 2405339158728
    # 1444529840 1444529872 1444529904 2405339158728
    lis1[0] = 5             # 接下来对lis1的数据进行修改
    lis1[4][0] = "yyy"      # 接下来对lis1的数据进行修改
    print(lis3)             # 1未变为5,列表内数据改变
    # [1, 2, 3, 4, ['yyy', 'ahaha']]
    print(lis1[4] is lis3[4])   # 浅拷贝备份中的可变数据类型等效于原函数内的数据
    # True

     

    浅拷贝只是直接将所有数据指向的内存地址复制一份关联到自己创建的数据,如图,创建了0xffff6666这个列表对象,但是列表内的指向不变

    当修改不可变数据类型时原函数指向变化,浅拷贝指向不变,浅拷贝不受影响

    当修改列表内的容器类型内的数据时,原列表与copy的列表都会受影响

    浅拷贝只能拷贝第一层的内存地址,当第一层的内存地址不变但内部数据改变时会受到影响

     

    import copy
    lis1 = [1, 2, 3, 4, ["xxx", "ahaha"]]
    lis3 = copy.deepcopy(lis1)  # 深拷贝
    print(lis1 is lis3)     # False
    print(id(lis1[0]), id(lis1[1]), id(lis1[2]), id(lis1[4]))
    print(id(lis3[0]), id(lis3[1]), id(lis3[2]), id(lis3[4]))
    1444529840 1444529872 1444529904 2407768538760
    1444529840 1444529872 1444529904 2407767069960

    深拷贝中可以看到对lis1内的小列表独立制造了一份,与原列表无关,如果在图中就是创建了一个0xffff5555的新列表,其他指向不变

     

    不可变数据直接关联的形式是由于更改原数据后原数据会有新的内存空间,不会修改原有空间,并且能节省空间

     

    结论:

    浅拷贝是直接将所有数据的内存地址复制一份关联到自己创建的数据

    深拷贝是会将可变不可变数据进行区分,并且将可变数据类型重新创建一份,不可变数据则直接关联到原数据

  • 相关阅读:
    希尔排序例子
    C
    重构最大堆的例子
    基于堆的优先队列和用优先队列排序的例子
    堆排序例子
    分治法示例
    三路划分的快速排序算法
    二叉搜索例子
    标准快速排序
    【转载】JAVA5新特性
  • 原文地址:https://www.cnblogs.com/achai222/p/12450929.html
Copyright © 2020-2023  润新知