Python—深浅拷贝理解

本文详细介绍了Python中的深拷贝和浅拷贝概念。对于可变数据类型,浅拷贝只复制顶层数据,内部引用仍指向原内存地址,而深拷贝则创建全新副本,包括所有嵌套数据。通过实例展示了两种拷贝在内存地址和数据修改上的区别,帮助理解这两种拷贝在实际编程中的应用。
摘要由CSDN通过智能技术生成

Python—深浅拷贝理解

目录:

  • Python的可变数据类型及不可变数据类型
  • Python浅拷贝
  • Python深拷贝
一、Python的可变数据类型及不可变数据类型
  1. 首先在开始理解Python的深浅拷贝前,我们需要明白Python的数据类型中哪些属于可变数据类型,哪些属于不可变的数据类型。

  2. Python不可变数据类型:

    • Number(数字)
    • String(字符串)
    • Tuple(元组)
  3. Python可变数据类型:

    • Set(集合)
    • List(列表)
    • Dictionary(字典)
  4. 可变数据类型及不可变数据类型的定义:

    • 可变数据类型:顾名思义,就是变量中对应的值是可以被修改的,即改了变量中对应的值的同时,内存地址不变。

    • 不可变数据类型:就是变量中对应的值是不可以被修改的,即改了变量中对应的值的同时,内存地址也会改变。

    • 对于两个(同一内存地址存储可变数据类型的数据)变量来说,当其中一个变量修改数据时,另一个变量所拿到的数据也是会发生改变。

    • 对于两个(同一内存地址存储不可变数据类型的数据)变量来说,当其中一个变量修改数据时,实际上是Python开辟新的内存地址存储修改后的数据,并将这个新的内存地址给该变量,另一个变量不会影响。即修改存储不可变得数据类型的变量,实际上是开辟新的内存地址给该变量,而不是之前的内存地址。

    • 下面是对可变数据类型和不可变数据类型的举例说明:

      # 可变数据类型
      a=[1,2,3]
      print("a:",a)
      print("内存地址:",id(a))
      a.append(67)
      print("a:",a)
      print("内存地址:",id(a))
      #上述代码运行结果:
      #	a: [1, 2, 3]
      #	内存地址: 1819894616256
      #	a: [1, 2, 3, 67]
      #	内存地址: 1819894616256
      
      # 不可变数据类型
      b=1
      print("b:",b)
      print("内存地址:",id(b))
      b=2
      print("b:",b)
      print("内存地址:",id(b))
      #代码运行结果:
      #	b: 1
      #	内存地址: 140711594170016
      #	b: 2
      #	内存地址: 140711594170048
      
二、Python浅拷贝
  • 定义:对于顶层数据(如 [1,2,3,[‘a’,‘b’]] 中;一整个列表就是顶层元素)来说,假如顶层数据是可变数据类型,则会开辟新的内存地址来存储(仅对于顶层数据),而假如顶层数据是不可变数据类型,则是会直接复制内存地址,不会开辟新的内存地址;对于非顶层数据则是直接复制其内存地址。

  • 下面是对浅拷贝的举例说明:

    #温馨提示:
    #如果是要使用不是copy库中的copy方法,而是直接使用 a.copy(),被拷贝的数据必须是可变数据类型的,否则运行时会报错。
    
    
    # 浅拷贝
    import copy
    a=1
    b=copy.copy(a)
    print("a 的内存地址为:",id(a))
    print("b的内存地址为:",id(b))
    #运行结果:
    #	a 的内存地址为: 140711594170016
    #	b的内存地址为: 140711594170016
    
    list1=[1,2,3,[55,'a']]
    list2=copy.copy(list1)
    print("list1的内存地址为:",id(list1))
    print("list2的内存地址为:",id(list2))
    print("list1[-1]:",list1[-1])
    print("list2[-1]:",list2[-1])
    print("list1[-1]的内存地址为:",id(list1[-1]))
    print("list2[-1]的内存地址为:",id(list2[-1]))
    list2[-1].append("jzj")
    print("修改list2[-1]的值后")
    print("list1的内存地址为:",id(list1))
    print("list2的内存地址为:",id(list2))
    print("list1[-1]:",list1[-1])
    print("list2[-1]:",list2[-1])
    print("list1[-1] 的内存地址为:",id(list1[-1]))
    print("list2[-1]的内存地址为:",id(list2[-1]))
    #运行结果:
    #	list1的内存地址为: 1932912303680
    #	list2的内存地址为: 1932912394048
    #	list1[-1]: [55, 'a']
    #	list2[-1]: [55, 'a']
    #	list1[-1]的内存地址为: 1932912300096
    #	list2[-1]的内存地址为: 1932912300096
    #	修改list2[-1]的值后
    #	list1的内存地址为: 1932912303680
    #	list2的内存地址为: 1932912394048
    #	list1[-1]: [55, 'a', 'jzj']
    #	list2[-1]: [55, 'a', 'jzj']
    #	list1[-1] 的内存地址为: 1932912300096
    #	list2[-1]的内存地址为: 1932912300096
    
三、Python深拷贝
  • 定义:将变量中对应的值复制到在新的内存地址中,而不是复制数据对应的内存地址。

  • 温馨提醒:在Python中无论是深拷贝还是浅拷贝,对于不可变类型的数据,都是复制其内存地址,而不是数据,因为一旦改变不可变类型的值,其内存地址也是会改变,所以复制其内存地址比复制其值能够提升性能、节省空间。

  • 下面是对深拷贝的举例说明:

    #深拷贝
    import copy
    list1=[1,2,3,[55,'a']]
    list2=copy.deepcopy(list1)
    print("list1的内存地址为:",id(list1))
    print("list2的内存地址为:",id(list2))
    print("list1[0]的内存地址为:",id(list1[0]))
    print("list2[0]的内存地址为:",id(list2[0]))
    print("list1[-1]:",list1[-1])
    print("list2[-1]:",list2[-1])
    print("list1[-1]的内存地址为:",id(list1[-1]))
    print("list2[-1]的内存地址为:",id(list2[-1]))
    list2[-1].append("jzj")
    print("修改list2[-1]的值后")
    print("list1的内存地址为:",id(list1))
    print("list2的内存地址为:",id(list2))
    print("list1[-1]:",list1[-1])
    print("list2[-1]:",list2[-1])
    print("list1[-1] 的内存地址为:",id(list1[-1]))
    print("list2[-1]的内存地址为:",id(list2[-1]))
    #运行结果:
    #	list1的内存地址为: 2107778465984
    #	list2的内存地址为: 2107778559936
    #	list1[0]的内存地址为: 140714265679520
    #	list2[0]的内存地址为: 140714265679520
    #	list1[-1]: [55, 'a']
    #	list2[-1]: [55, 'a']
    #	list1[-1]的内存地址为: 2107778469568
    #	list2[-1]的内存地址为: 2107778559232
    #	修改list2[-1]的值后
    #	list1的内存地址为: 2107778465984
    #	list2的内存地址为: 2107778559936
    #	list1[-1]: [55, 'a']
    #	list2[-1]: [55, 'a', 'jzj']
    #	list1[-1] 的内存地址为: 2107778469568
    #	list2[-1]的内存地址为: 2107778559232
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值