要点:
1. 赋值, 没有创作新对象
2. 浅拷贝,只拷贝第一层内容. 浅copy的两种方法: 1.切片[:] 2.list.copy()
3. 深拷贝,把这个对象内部的内容全部拷贝, 引入copy模块. deepcopy()
赋值:
列表的赋值:
lst1 = ["A","B","C","D"] lst2 = lst1 print(lst1) #['A', 'B', 'C', 'D'] print(lst2) #['A', 'B', 'C', 'D']
lst1 = ["A","B","C","D"] lst1.append("e") lst2 = lst1 print(lst1) #['A', 'B', 'C', 'D', 'e'] print(lst2) #['A', 'B', 'C', 'D', 'e']
字典的赋值:
dic = {"A":"a","B":"b"} dic1 = dic print(dic) #{'A': 'a', 'B': 'b'} print(dic1) #{'A': 'a', 'B': 'b'} dic = {"A":"a","B":"b"} dic["C"]="c" dic1 = dic print(dic) #{'A': 'a', 'B': 'b', 'C': 'c'} print(dic1) #{'A': 'a', 'B': 'b', 'C': 'c'}
赋值图示:
对于list,dict,set来说,直接赋值就是把内存地址交给变量,并不是复制一份内容.
所以lst1的内存指向和lst2的内存指向是一样的.
lst1发生改变,lst2也会跟着发生改变.
浅copy: 浅copy和赋值不一样. 对于浅copy来说,lst2 的第一层创建的是新的内存地址。而从第二层开始,指向的是同一个内存地址,对于第二层以及更深的层数来说,保持一致性。浅copy只会拷贝第一层.
lst1 = ["何炅","杜海涛","周渝民"] lst2 = lst1.copy() lst1.append("李嘉诚") #lst1 的添加不会对 lst2产生影响 print(lst1) #['何炅', '杜海涛', '周渝民', '李嘉诚'] print(lst2) #['何炅', '杜海涛', '周渝民'] print(id(lst1)) #20971888 print(id(lst2)) #20329336
如上图所示,append("杨逍")改变第一层的时候,已经copy的lst2不会发生改变.
lst1 和 lst2 的内存地址和内容也不一样.
浅copy中的嵌套: 第一层都是独立的的。从第二层开始都是是公用的.
lst1 = ["何炅","杜海涛","周渝民",["周笔畅"]] lst2 = lst1.copy() lst1[3].append("李嘉诚") #在lst1 的子列表中添加, 对lst2 也会有影响 print(lst1) #['何炅', '杜海涛', '周渝民', ['周笔畅', '李嘉诚']] print(lst2) #['何炅', '杜海涛', '周渝民', ['周笔畅', '李嘉诚']]
print(id(lst1),id(lst1[3])) #20198264 20840816
print(id(lst2),id(lst1[3])) #20840616 20840816
lst1 和 lst2的整体的内存地址不一样, 但是子列表 lst1[3]和lst2[3] 的内存地址是一样的.
如上图所示, 当lst1第二层改变的时候,lst2的第二层也会跟着改变. 比如说在lst1的小列表里添加append("小昭").
深copy: 对于深copy来说,两个是完全独立的,改变任意一个的元素(无论是多少层),另一个绝不会改变。
import copy lst1 = ["何炅","杜海涛","周渝民",["周笔畅"]] lst2 = copy.deepcopy(lst1) lst1[3].append("无敌是多么寂寞") print(lst1) #['何炅', '杜海涛', '周渝民', ['周笔畅', '无敌是多么寂寞']] print(lst2) #['何炅', '杜海涛', '周渝民', ['周笔畅']] print(id(lst1), id(lst1[3]))#24505120 24504880 print(id(lst2), id(lst2[3]))#24505880 24505840
深copy之后的所有的 id地址都是不一样的.包括子列表中的id地址
