一、内存地址
内存:
左边:变量或者引用
右边:对象,数据
lst1 = ["小王", "小明", "小黑", "小花"]
lst2 = lst1 # 列表, 进行赋值操作. 实际上是引用内存地址的赋值. 内存中此时只有一个列表. 两个变量指向一个列表
lst2.append("小红") # 对期中的一个进行操作. 两个都跟着变
print(lst2)
print(lst1)
# 结果
["小王", "小明", "小黑", "小花", "小红"]
["小王", "小明", "小黑", "小花", "小红"]
print(id(lst1),id(lst2)) # 内存地址一样
- 对于list,set,dict来说,直接赋值。其实是把内存地址交给变量,并不是复制一份内容。
- 所以,Ist1的内存指向和Ist2是一样的。Ist1改变了,Ist2也发生了改变
二、浅拷贝 copy 创建新对象
创建新对象,内存地址不同
lst1 = ["赵本山", "刘能", "赵四"]
lst2 = lst1.copy() # lst2 和lst1 不是一个对象了
print(id(lst1), id(lst2))
#2348178624968 2348178625480
2.1 浅拷贝 copy
lst1 = ["赵本山", "刘能", "赵四"]
lst2 = lst1.copy() # lst2 和lst1 不是一个对象了
lst1.append("谢大脚")
print(lst1, lst2)
print(id(lst1), id(lst2))
# ['赵本山', '刘能', '赵四', '谢大脚'] ['赵本山', '刘能', '赵四']
# 1221664068040 1221664068552
2.2 浅拷贝 [:]
lst1 = ["赵本山", "刘能", "赵四"]
lst2 = lst1[:] # 切片会产生新的对象,从头到尾
lst1.append("谢大脚")
print(lst1, lst2)
print(id(lst1), id(lst2))
# ['赵本山', '刘能', '赵四', '谢大脚'] ['赵本山', '刘能', '赵四']
# 2843786826184 2843786826696
三、深拷贝
3.1 浅拷贝问题
lst1 = ["超人", "七龙珠", "葫芦娃", "山中小猎人", ["金城武", "王力宏", "渣渣辉"]]
lst2 = lst1.copy() # 浅拷贝,拷贝第一层(内部不会再复制)
lst1[4].append("大阳哥")
print(lst1)
print(lst2)
# ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']]
# ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']]
结果:
两个1st完全不一样。内存地址和内容也不一样。发现实现了内存的拷贝。
3.2 深拷贝
import copy
lst1 = ["超人", "七龙珠", "葫芦娃", "山中小猎人", ["金城武", "王力宏", "渣渣辉"]]
lst2 = copy.deepcopy(lst1) # 把lst1扔进去进行深度拷贝 , 包括内部的所有内容进行拷贝
lst1[4].append("大阳哥")
print(lst1, lst2)
# ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']]
# ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉']]
- 都不一样了。
- 深度拷贝:把元素内部的元素完全进行拷贝复制。不会产生一个改变另一个跟着改变的问题
四、为什么要有深浅拷贝
- 创建对象是类实例化的一个过程,先开内存,然后往里面写东西
- 拷贝比创建对象的过程要快