信息发布→ 登录 注册 退出

Python中copy和deepcopy的使用分析

发布时间:2026-01-11

点击量:
目录
  • 一、定义
  • 二、区别
  • 三、代码分析深浅拷贝
    • 浅拷贝仅拷贝对象本身
      • 不可变类型的浅拷贝
      • 可变类型的浅拷贝
    • 深拷贝完全复制独立
      • 不可变类型的深拷贝
      • 可变类型的深拷贝
  • 四、总结

    一、定义

    浅拷贝:创建一个新的对象,只拷贝子对象的引用(内部的内存地址都不相同)。这意味着,如果原对象的子对象发生变化,拷贝后的对象也会受到影响。

    深拷贝:创建一个新的对象,并递归地拷贝原对象的所有子对象(内部以及外部的内存地址都不相同)。这意味着,即使原对象的子对象发生变化,拷贝后的对象也不会受到影响。

    二、区别

    浅拷贝copy:

    第一种情况:复制的 对象中无 复杂 子对象,原来值的改变并不会影响浅复制的值,同时浅复制的值改变也并不会影响原来的值。原来值的id值与浅复制原来的值不同。

    第二种情况:复制的对象中有 复杂 子对象 (例如列表中的一个子元素是一个列表), 改变原来的值 中的复杂子对象的值 ,会影响浅复制的值。

    深拷贝deepcopy:完全复制独立,包括内层列表和字典。

    三、代码分析深浅拷贝

    浅拷贝仅拷贝对象本身

    不可变类型的浅拷贝

    如果复制不可变类型的数据(字符串、数值型、布尔值),和“=”赋值情况一样,浅拷贝的对象和原数据对象是相同的内存地址。

    import copy
    a = '哈哈'
    b = a
    c = copy.copy(a)
    print('原数据的内存地址:', id(a))
    print('浅拷贝对象的内存地址:', id(c))
    print('=赋值对象的内存地址:', id(c))
    print('\n')

    可变类型的浅拷贝

    情况一:不存在嵌套类型的可变类型数据(列表、字典、集合)。列表本身的浅拷贝对象的地址

    原对象的地址是不同的,因为列表是可变数据类型。因此改变原对象的值并不会影响浅复制的

    值。

    list1 = [1, 2, 3]
    list2 = copy.copy(list1)
    print('原数据的内存地址:', id(list1))
    print('浅拷贝的内存地址:', id(list2))
    # 测试,修改list1对象元素的值,不会改变list2的值(相互不影响)
    list1[0] = 8
    print(list1)
    print(list2)

    情况二:如果可变类型的数据中存在嵌套的结构。浅拷贝只复制最外层的数据,导致内存地址发

    变化,嵌套数据的内存地址不会变。因此改变原对象中的嵌套对象的值,会影响浅复制的值。

    list3 = [1, 2, [3, 4, 5]]
    list4 = copy.copy(list3)
    print('原数据的内存地址:', id(list3))
    print('浅拷贝的内存地址:', id(list4))
    print('\n')
    print('原数据的内存地址:', id(list3[0]))
    print('浅拷贝的内存地址:', id(list4[0]))
    print('\n')
    print('原数据的内存地址:', id(list3[2]))
    print('浅拷贝的内存地址:', id(list4[2]))
    # 测试
    list3[2][0] = 8  # 改变list3嵌套列表的数值,浅拷贝的值也发生变化
    print(list3)
    print(list4)

    深拷贝完全复制独立

    不可变类型的深拷贝

    number = 5
    number2 = copy.deepcopy(number)
    print('原数据的内存地址:', id(number))
    print('深拷贝的内存地址:', id(number2))

    可变类型的深拷贝

    原对象的值和复制后的值不相互影响。

    情况一:不存在嵌套类型的可变类型数据(列表、字典、集合)

    list1 = [1, 2, 3]
    list2 = copy.copy(list1)
    list33 = copy.deepcopy(list1)
    print('原数据的内存地址:', id(list1))
    print('浅拷贝的内存地址:', id(list2))
    print('深拷贝的内存地址:', id(list33))

    情况二:如果可变类型的数据中存在嵌套的结构

    list3 = [1, 2, [3, 4, 5]]
    list4 = copy.copy(list3)
    list55 = copy.deepcopy(list3)
    print('原数据的内存地址:', id(list3))
    print('浅拷贝的内存地址:', id(list4))
    print('深拷贝的内存地址:', id(list55))
    print('\n')
    print('原数据的内存地址:', id(list3[0]))
    print('浅拷贝的内存地址:', id(list4[0]))
    print('深拷贝的内存地址:', id(list55[0]))
    print('\n')
    print('原数据的内存地址:', id(list3[2]))
    print('浅拷贝的内存地址:', id(list4[2]))
    print('深拷贝的内存地址:', id(list55[2]))

    四、总结

    只有浅拷贝拷贝有嵌套的可变类型时,改变原对象中嵌套内的数据,拷贝对象的值也会改变,即

    原对象与拷贝对象的值相互影响。

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!