17、人工智能Python基础之彻底搞懂赋值、浅拷贝、深拷贝的区别_笔记# 可变对象与不可变对象# 可变对象的可变性实质上是指 更改可变对象中的子对象 比如list中的item对象# 不可变对象:string tuple number# 可变对象:列表 字典# 可变对象与不可变对象的赋值有区别:# 不可变对象进行重新赋值的时候,实际上是将原始值丢弃,将变量指向一个新值,一个新的内存地址# 可变对象的赋值就是创建了对象的一个新的引用(别名),并不开辟一个新的内存空间# 浅拷贝与深拷贝只针对可变对象# 浅拷贝:只拷贝父对象,不拷贝子对象# 只拷贝了最外围的对象本身,内部的子对象都只是拷贝了一个引用而已# 浅拷贝:创建一个新的父对象,但它包含的是对原始对象中所有子项的引用,如果用引用的方式修改其中一个对象,另外一个也会改变# 常见操作:列表的切片[:]操作、使用工厂函数如list/dir/set操作,对象的copy()函数、copy模块的copy()函数(两个一模一样的双胞胎)# 深拷贝:会拷贝父对象和子对象并且递归的方式拷贝所有的子对象,当对象子对象进行更改的时候,原始对象不会改变。# 常见操作:copy模块的deepcopy()函数# 深拷贝不是拷贝子对象的引用 而是拷贝了数据结构# -*- coding: utf-8 -*-__author__ = 'dongfangyao'__date__ = '2018/1/15 下午11:07'__product__ = 'PyCharm'__filename__ = 'copy1'import copy# 赋值 浅拷贝 深拷贝# python 可变对象list dict 不可变对象 string tuple number# str1 = 'dfy'# print(id(str1))# str1 = 'dongfangyao'# print(id(str1))## a = [1, 2, 3]# a1 = a# print(id(a))# print(id(a1))# a[1] = 22# print(a)# print(a1)# 浅拷贝# [:] list() set() copy.copy() list.copy()a = [1, 2, 3]b = [11, 22, 33]c = [111, 222, 333]list1 = [a, b, c]print('list1的内存地址:' + str(id(list1)))print('_'*20)list2 = list1# print(id(list1) == id(list2))list3 = list1[:]# print(id(list1) == id(list3))# print(id(list1[0][1]) == id(list3[0][1]))# a[0] = 1111# list1[0] = 'dfy'# list1[1][0] = '1111'# print(list1)# print(list3)# 深拷贝 copy.deepcopy()list4 = copy.deepcopy(list1)print(id(list1) == id(list4))print(id(list1[0]) == id(list4[0]))print(id(list1[0][1]) == id(list4[0][1]))# a[0] = 1111# list1[0] = 'dfy'list1[1][0] = '1111'print(list1)print(list4)复制代码import copylist_0 = ["A", "B", ["C", "D"], "E"]list_1 = copy.copy(list_0)list_2 = list_0.copy()list_3 = list_0[:]list_4 = list(list_0)list_5 = list_0# --- 深拷贝的拷贝方式 ---list_d = copy.deepcopy(list_0)# --- 深浅拷贝与赋值的区别 ---# 1. 对第一层数据进行赋值list_0[0] = "X0"list_1[0] = "X1"list_2[0] = "X2"list_3[0] = "X3"list_4[0] = "X4"list_5[0] = "X5"list_d[0] = "Xd"# 2. 对第二层的list引用进行赋值# list_0[2][0] = "Y0"# list_1[2][0] = "Y1"# list_2[2][0] = "Y2"# list_3[2][0] = "Y3"# list_4[2][0] = "Y4"# list_5[2][0] = "Y5"# list_d[2][0] = "Yd"# 3. 对第一层数据进行赋值# list_0[3]= "Z0"# list_1[3]= "Z1"# list_2[3]= "Z2"# list_3[3]= "Z3"# list_4[3]= "Z4"# list_5[3]= "Z5"# list_d[3]= "Zd"print(list_0)print(list_1)print(list_2)print(list_3)print(list_4)print(list_5)print(list_d)lst = []a = [1]lst.append(a)a[0] = 2lst.append(a)print(id(a))print(lst)a = [3]print(id(a))lst.append(a)复制代码第一次是赋值给a的子对象,没有改变a的地址,然后lst中存的又是a的引用,改变了a的子对象的值,就改变了lst中存的引用的值,所以前两个输出是[2] ;第二次赋值赋给a本身的父对象,因为一个变量同时只能指向一个内存地址的数据,所以a的地址改变了,lst中存入了一个新的引用,所以第三个的输出是[3]