Python 深浅拷贝

要点:
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地址


原文地址:https://www.cnblogs.com/kenD/p/9416017.html