在python中的数据类型可以分为两大类:
1. 简单数据类型
(1) bool
(2) int
(3) float
(4) str
2. 复杂数据类型
(1)list
(2)tuple
(3)set
(4)dict
那么对于简单数据类型变量python在内存中是如何保存的呢?
str="hello world"
str_x=str
print(id(str))
print(id(str_x))
'''
运行结果:
2624680986672
2624680986672
'''
那么内存图就是这样的:
可以看到str赋值给str_x,存在str_x中的是和str一样的内存地址,str跟str_x指向了同一个内存地址,这是为了节省内存,采用的引用。
可以看到new hello world一个新值赋值给str,取消之前的内存地址,进行垃圾回收,这是因为,创建变量并且是新变量,就创建新的地址,再将内存地址赋值给变量。
那么复杂的数据类型在python中该如何保存呢?
x=1
print(id(x))
y=2
print(id(y))
z=3
print(id(z))
print("----------------")
str=[x,y,z]
print(str)
print(id(str))
print("----------------")
print(id(str[0]))
print(id(str[1]))
print(id(str[2]))
'''
运行结果:
1931042976
1931043008
1931043040
----------------
[1, 2, 3]
2343440058440
----------------
1931042976
1931043008
1931043040
'''
那么内存图就是这样:
列表中保存的实际上是x,y,z的引用地址。
上面这些都理解了就可以理解什么是浅拷贝,什么是深拷贝?
用copy()进行浅拷贝(或者copy.copy()也可以):
#浅层拷贝
list=["hello","hellow","hi"]
list1=["name","age"]
list.append(list1)
print(list)
#拷贝
list2=list.copy()
print(list2)
list.append("area")
print(list)
print(list2)
list1.clear()
print(list)
print(list2)
'''
运行结果:
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age'], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', [], 'area']
['hello', 'hellow', 'hi', []]
'''
分析:拷贝后,向list里增加area,假设浅拷贝是引用的是地址!可以看到list里面成功了,但list1里面却没有成功,说明假设不成立,是开辟的新地址。继续往下看,我们清除了list1的内容,list跟list2中的内嵌列表都一样变成空的。可以得出结论,内嵌列表是引用地址。
结论:
对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,拷贝的都是内存地址,是引用。
运用copy.deepcopy()进行深拷贝:
#深层拷贝
import copy
list=["hello","hellow","hi"]
list1=["name","age"]
list.append(list1)
print(list)
#拷贝
list2=copy.deepcopy(list)
print(list2)
list.append("area")
print(list)
print(list2)
list1.clear()
print(list)
print(list2)
'''
运行结果:
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age'], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', [], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
'''
分析:
可以看到添加area跟清空list列表都对深层拷贝的list2无效,这是因为深层拷贝不仅第一层重新分配了内存地址,内嵌套的可变数据类型都重新开辟一块内存空间。
结论:深拷贝,对所有东西进行递归拷贝,并全部重新分配了存储空间。
来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!