Python 深浅拷贝

矫情吗;* 2023-06-01 06:21 113阅读 0赞

一、前言

Python的数据类型:

  • 不可变数据类型:数值类型(int、float)、字符串、元组
  • 可变数据类型:列表、字典、集合

深浅copy的模块(copy):

  • copy.copy() 浅拷贝
  • copy.deepcopy() 深拷贝

二、不可变数据类型的深浅拷贝

2.1 浅拷贝

  1. 1 #!/usr/bin/env python
  2. 2 # -*-coding:utf-8-*-
  3. 3
  4. 4 """
  5. 5 @author:fyh
  6. 6 @time:2019/6/5
  7. 7 """
  8. 8 import copy
  9. 9
  10. 10 a = 123
  11. 11 b = copy.copy(a)
  12. 12 print(b)
  13. 13 print(id(a))
  14. 14 print(id(b))
  15. 15
  16. 16 # 输出结果
  17. 17 # 123
  18. 18 # 1891531600
  19. 19 # 1891531600
  20. 20
  21. 21 s1 = "abc"
  22. 22 s2 = copy.copy(s1)
  23. 23 print(s2)
  24. 24 print(id(s1))
  25. 25 print(id(s2))
  26. 26
  27. 27 # 输出结果
  28. 28 # abc
  29. 29 # 2586689354584
  30. 30 # 2586689354584

通过上面的示例可以看出:不可变类型进行浅拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用。

2.2 深拷贝

  1. 1 #!/usr/bin/env python
  2. 2 # -*-coding:utf-8-*-
  3. 3
  4. 4 """
  5. 5 @author:fyh
  6. 6 @time:2019/6/5
  7. 7 """
  8. 8 import copy
  9. 9
  10. 10 a = 123
  11. 11 b = copy.deepcopy(a)
  12. 12 print(b)
  13. 13 print(id(a))
  14. 14 print(id(b))
  15. 15
  16. 16 # 输出结果
  17. 17 # 123
  18. 18 # 1891531600
  19. 19 # 1891531600
  20. 20
  21. 21 s1 = "abc"
  22. 22 s2 = copy.deepcopy(s1)
  23. 23 print(s2)
  24. 24 print(id(s1))
  25. 25 print(id(s2))
  26. 26
  27. 27 # 输出结果
  28. 28 # abc
  29. 29 # 2586689354584
  30. 30 # 2586689354584

通过上面的示例可以看出:不可变类型进行深拷贝不会给拷贝的对象开辟新的内存空间,也是拷贝了这个对象的引用。

原理如下图:

1077055-20190906160821365-787334464.png

三、可变类型的深浅拷贝

3.1 浅拷贝

  1. 1 #!/usr/bin/env python3
  2. 2
  3. 3 """
  4. 4 @author:fyh
  5. 5 """
  6. 6 import copy
  7. 7
  8. 8
  9. 9 my_list1 = ['苹果', '鸭梨']
  10. 10 my_list2 = copy.copy(my_list1)
  11. 11 print("my_list1:", id(my_list1), "my_list2:", id(my_list2))
  12. 12 my_list1[0] = '香蕉'
  13. 13 print(my_list1, my_list2)
  14. 14
  15. 15 # 结果
  16. 16 # my_list1: 140246877880712 my_list2: 140246877802120
  17. 17 # ['香蕉', '鸭梨'] ['苹果', '鸭梨']
  18. 18
  19. 19 # 结论:对可变类型可以进行浅拷贝,会对对象开辟新的内存空间
  20. 20
  21. 21 my_list3 = ['苹果', '鸭梨', ['橘子', '橙子']]
  22. 22 my_list4 = copy.copy(my_list3)
  23. 23 print("my_list3:", id(my_list3), "my_list4:", id(my_list4))
  24. 24 # 结果 my_list3: 140703644308360 my_list4: 140703644310728
  25. 25
  26. 26 print("my_list3[2]:", id(my_list3[2]), "my_list4[2]:", id(my_list4[2]))
  27. 27 # 结果:my_list3[2]: 140309865347272 my_list4[2]: 140309865347272
  28. 28
  29. 29 my_list3[2][0] = '凤凰'
  30. 30 print("my_list3", my_list3, "my_list4", my_list4)
  31. 31 # 结果:my_list3 ['苹果', '鸭梨', ['凤凰', '橙子']] my_list4 ['苹果', '鸭梨', ['凤凰', '橙子']]
  32. 32
  33. 33 my_list3[0] = "aa"
  34. 34
  35. 35 print("my_list3", my_list3, "my_list4", my_list4)
  36. 36 # 结果:my_list3 ['aa', '鸭梨', ['凤凰', '橙子']] my_list4 ['苹果', '鸭梨', ['凤凰', '橙子']]
  37. 37
  38. 38 # 结论:浅拷贝只会对对象的第一层对象进行拷贝

结论:copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象。

原理如下图:

未修改前:

1077055-20190906211532377-511259810.png

修改后的:

1077055-20190906211649361-171803498.png

3.2 深拷贝

  1. 1 #!/usr/bin/env python3
  2. 2
  3. 3 """
  4. 4 @author:fyh
  5. 5 """
  6. 6 import copy
  7. 7
  8. 8 list1 = [1, 2]
  9. 9 list2 = copy.deepcopy(list1)
  10. 10 print("list1", id(list1), "list2", id(list2))
  11. 11 # 结果:list1 140200541024008 list2 140200540991112
  12. 12
  13. 13 list1[0] = 3
  14. 14 print(list1, list2)
  15. 15 # 结果:[3, 2] [1, 2]
  16. 16
  17. 17 list3 = [3, 4, [5, 6]]
  18. 18 list4 = copy.deepcopy(list3)
  19. 19 print("list3", id(list3), "list4", id(list4))
  20. 20 # 结果:list3 140370543248904 list4 140370543250184
  21. 21 print("list3[2]", id(list3[2]), "list4[2]", id(list4[2]))
  22. 22 # print("list3", id(list3), "list4", id(list4))
  23. 23 list3[2][0] = 7
  24. 24 print(list3, list4)
  25. 25 # 结果:[3, 4, [7, 6]] [3, 4, [5, 6]]

结论:可变类型进行深拷贝会对该对象到最后一个可变类型的每一层对象就行拷贝, 对每一层拷贝的对象都会开辟新的内存空间进行存储。

原理如下图:

1077055-20190906212518352-1630813463.png

四、总结

  • 浅拷贝使用copy.copy函数
  • 深拷贝使用copy.deepcopy函数
  • 不管是给对象进行深拷贝还是浅拷贝,只要拷贝成功就会开辟新的内存空间存储拷贝的对象。
  • 浅拷贝和深拷贝的区别是:

    • 浅拷贝最多拷贝对象的一层,深拷贝可能拷贝对象的多层。

转载于:https://www.cnblogs.com/fengyuhao/p/11475543.html

发表评论

表情:
评论列表 (有 0 条评论,113人围观)

还没有评论,来说两句吧...

相关阅读

    相关 深浅拷贝

    深拷贝和浅拷贝是指在赋值时或将一个变量的值复制到另一个变量时,拷贝出来的变量和原变量之间的关系。 浅拷贝就是在复制的时候,复制的只是变量的引用,而不是变量的实际值。所以如果对

    相关 深浅拷贝

    深浅copy   先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单词音译过来的,那什么是copy? copy其实就是复制一份,也就是所谓的抄一份。深浅

    相关 深浅拷贝

    转载:[详解Java中的clone方法][Java_clone]  虽然是转载,这里大概说一下自己的理解:   无论是深拷贝还是浅拷贝,只要是想让对象具有拷贝的功能

    相关 Python 深浅拷贝

    一、前言 Python的数据类型: 不可变数据类型:数值类型(int、float)、字符串、元组 可变数据类型:列表、字典、集合 深浅copy的模块(co

    相关 python深浅拷贝

    Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果。 下面本文就通过简单的例子介绍一下这些概念之间的差别。 要想

    相关 python深浅拷贝

    在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, a

    相关 深浅拷贝

    1. 基础数据类型补充 之前已经发过大多数的基本数据类型的知识 join()把传递进去的参数进行迭代. 获取到的每个元素和前面的\进行拼接. 得到的是字符串 spl