1. 17、人工智能Python基础之彻底搞懂赋值、浅拷贝、深拷贝的区别_笔记
    2. # 可变对象与不可变对象
    3. # 可变对象的可变性实质上是指 更改可变对象中的子对象 比如list中的item对象
    4. # 不可变对象:string tuple number
    5. # 可变对象:列表 字典
    6. # 可变对象与不可变对象的赋值有区别:
    7. # 不可变对象进行重新赋值的时候,实际上是将原始值丢弃,将变量指向一个新值,一个新的内存地址
    8. # 可变对象的赋值就是创建了对象的一个新的引用(别名),并不开辟一个新的内存空间
    9. # 浅拷贝与深拷贝只针对可变对象
    10. # 浅拷贝:只拷贝父对象,不拷贝子对象
    11. # 只拷贝了最外围的对象本身,内部的子对象都只是拷贝了一个引用而已
    12. # 浅拷贝:创建一个新的父对象,但它包含的是对原始对象中所有子项的引用,如果用引用的方式修改其中一个对象,另外一个也会改变
    13. # 常见操作:列表的切片[:]操作、使用工厂函数如list/dir/set操作,对象的copy()函数、copy模块的copy()函数(两个一模一样的双胞胎)
    14. # 深拷贝:会拷贝父对象和子对象并且递归的方式拷贝所有的子对象,当对象子对象进行更改的时候,原始对象不会改变。
    15. # 常见操作:copy模块的deepcopy()函数
    16. # 深拷贝不是拷贝子对象的引用 而是拷贝了数据结构
    17. # -*- coding: utf-8 -*-
    18. __author__ = 'dongfangyao'
    19. __date__ = '2018/1/15 下午11:07'
    20. __product__ = 'PyCharm'
    21. __filename__ = 'copy1'
    22. import copy
    23. # 赋值 浅拷贝 深拷贝
    24. # python 可变对象list dict 不可变对象 string tuple number
    25. # str1 = 'dfy'
    26. # print(id(str1))
    27. # str1 = 'dongfangyao'
    28. # print(id(str1))
    29. #
    30. # a = [1, 2, 3]
    31. # a1 = a
    32. # print(id(a))
    33. # print(id(a1))
    34. # a[1] = 22
    35. # print(a)
    36. # print(a1)
    37. # 浅拷贝
    38. # [:] list() set() copy.copy() list.copy()
    39. a = [1, 2, 3]
    40. b = [11, 22, 33]
    41. c = [111, 222, 333]
    42. list1 = [a, b, c]
    43. print('list1的内存地址:' + str(id(list1)))
    44. print('_'*20)
    45. list2 = list1
    46. # print(id(list1) == id(list2))
    47. list3 = list1[:]
    48. # print(id(list1) == id(list3))
    49. # print(id(list1[0][1]) == id(list3[0][1]))
    50. # a[0] = 1111
    51. # list1[0] = 'dfy'
    52. # list1[1][0] = '1111'
    53. # print(list1)
    54. # print(list3)
    55. # 深拷贝 copy.deepcopy()
    56. list4 = copy.deepcopy(list1)
    57. print(id(list1) == id(list4))
    58. print(id(list1[0]) == id(list4[0]))
    59. print(id(list1[0][1]) == id(list4[0][1]))
    60. # a[0] = 1111
    61. # list1[0] = 'dfy'
    62. list1[1][0] = '1111'
    63. print(list1)
    64. print(list4)
    65. 复制代码
    66. import copy
    67. list_0 = ["A", "B", ["C", "D"], "E"]
    68. list_1 = copy.copy(list_0)
    69. list_2 = list_0.copy()
    70. list_3 = list_0[:]
    71. list_4 = list(list_0)
    72. list_5 = list_0
    73. # --- 深拷贝的拷贝方式 ---
    74. list_d = copy.deepcopy(list_0)
    75. # --- 深浅拷贝与赋值的区别 ---
    76. # 1. 对第一层数据进行赋值
    77. list_0[0] = "X0"
    78. list_1[0] = "X1"
    79. list_2[0] = "X2"
    80. list_3[0] = "X3"
    81. list_4[0] = "X4"
    82. list_5[0] = "X5"
    83. list_d[0] = "Xd"
    84. # 2. 对第二层的list引用进行赋值
    85. # list_0[2][0] = "Y0"
    86. # list_1[2][0] = "Y1"
    87. # list_2[2][0] = "Y2"
    88. # list_3[2][0] = "Y3"
    89. # list_4[2][0] = "Y4"
    90. # list_5[2][0] = "Y5"
    91. # list_d[2][0] = "Yd"
    92. # 3. 对第一层数据进行赋值
    93. # list_0[3]= "Z0"
    94. # list_1[3]= "Z1"
    95. # list_2[3]= "Z2"
    96. # list_3[3]= "Z3"
    97. # list_4[3]= "Z4"
    98. # list_5[3]= "Z5"
    99. # list_d[3]= "Zd"
    100. print(list_0)
    101. print(list_1)
    102. print(list_2)
    103. print(list_3)
    104. print(list_4)
    105. print(list_5)
    106. print(list_d)
    107. lst = []
    108. a = [1]
    109. lst.append(a)
    110. a[0] = 2
    111. lst.append(a)
    112. print(id(a))
    113. print(lst)
    114. a = [3]
    115. print(id(a))
    116. lst.append(a)
    117. 复制代码
    118. 第一次是赋值给a的子对象,没有改变a的地址,然后lst中存的又是a的引用,改变了a的子对象的值,就改变了lst中存的引用的值,所以前两个输出是[2]
    119. 第二次赋值赋给a本身的父对象,因为一个变量同时只能指向一个内存地址的数据,所以a的地址改变了,lst中存入了一个新的引用,所以第三个的输出是[3]