首先要了解什么是深浅拷贝,我们就要知道一个知识点:什么是可变类型?什么是不可变类型
"""
不可变类型:当改变值得时候,会申请一块新的内存空间,不再是原来的那一块内存空间。
而整数类型、浮点型、字符串、元组、布尔类型都是不可变类型。
例如:
>>> a = 1
>>> print(id(a))
2282593282352
>>> a = 2
>>> print(id(a))
2282593282384
>>> a = "佩奇"
>>> print(id(a))
2282595304144
>>> a = 1.23
>>> print(id(a))
2282593912240
>>> a = (1,2)
>>> print(id(a))
2282595316608
>>> a = True
>>> print(id(a))
140712455141480
>>>他们的id地址都是不一样的,所以整数类型、浮点型、字符串、元组、布尔类型都是不可变类型。
可变类型:就是这个数据类型的值在不改变这一块内存空间前提下,而去改变这个数据类型的值。
而列表类型和字典类型就是可变类型
例如:列表类型
>>> a = ["佩奇","年龄",18]
>>> print(id(a))
2286422249792
>>> a[0]="乔治"
>>> print(a)
[‘乔治‘, ‘年龄‘, 18]
>>> print(id(a))
2286422249792
>>>在列表中将佩奇换成乔治,id地址没有发生变化zi
例如:字典类型
>>> a = {"name":"佩奇","age":18}
>>> print(id(a))
1625026357248
>>> a["name"] = "乔治"
>>> print(a)
{‘name‘: ‘乔治‘, ‘age‘: 18}
>>> print(id(a))
1625026357248
>>>在在列表中将佩奇换成乔治,id地址没有发生变化
"""
了解了什么是可变类型,什么是不可变类型,接下来就是我们要讲的重点python中的深浅拷贝
"""
浅拷贝:
浅拷贝就是把原列表第一层的内存地址不加区分的完全copy一份给新列表,简单来说就是拷贝了一下原列表产生了一个新的列表。
例如:
>>> a = ["佩奇",18,["乔治",16]]
>>> b = a.copy()
>>> print(b)
[‘佩奇‘, 18, [‘乔治‘, 16]]
>>> print(id(a))
1621358543552
>>> print(id(b))
1621358543616
>>>虽然id地址发生了变化,但是仅仅只是a,b列表整体id地址发生了变化,也就是第一层的内存地址变了,但是a,b列表内部的id地址并没有发生变化
如下我们查看“佩奇“,18,[‘乔治‘, 16],的id地址
>>> print(id(a[0]),id(a[1]),id(a[2]))
1621358494416 1621356473168 1621358268608
>>> print(id(b[0]),id(b[1]),id(b[2]))
1621358494416 1621356473168 1621358268608
>>>
这样的话,如果我们改变a列表的值,b列表的值会不会改变
例如:
>>> a[0] = "哥哥"
>>> a[1] = 20
>>> a[2][0] = "弟弟"
>>> a[2][1] = 18
>>> print(a)
[‘哥哥‘, 20, [‘弟弟‘, 18]]
>>> print(b)
[‘佩奇‘, 18, [‘弟弟‘, 18]]
>>>我们发现字符串类型和整数类型不会改变,但是列表类型里面的值发生了改变
总结:浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是原对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。浅拷贝中,不可变类型不会随着原列表的变化而变化,但是可变量类型,列表、字典会跟着原列表的变化而变化。
"""
所以想要copy得到新列表与原列表的改操作完全独立开,必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深拷贝
深拷贝:
完全拷贝了一个副本,容器内部元素地址都不一样
"""
首先我们需要导入一个模块copy,有一个deepcopy功能
举例说明:
>>>import copy
>>>a = ["佩奇",18,["乔治",16]]
>>>b = copy.deepcopy(a)
>>>print(b)
[‘佩奇‘, 18, [‘乔治‘, 16]]
>>>print(id(a))
1817894894656
>>>print(id(b))
1817894892864
接下来改变a列表的值,看b列表中的可变类型是否发生变化
>>> a[0] = "哥哥"
>>> a[1] = 20
>>> a[2][0] = "弟弟"
>>> a[2][1] = 18
>>> print(a)
[‘哥哥‘, 20, [‘弟弟‘, 18]]
>>> print(b)
[‘佩奇‘, 18, [‘乔治‘, 16]]
"""
总结:深拷贝是将两个列表完全独立开,在另一块地址中创建一个新的容器,同时容器内的元素的地址也是新开辟的,仅仅是内容相同而已,是完全的副本。也就是说( 新瓶装新酒 )。所以想要copy得到新列表与原列表的改操作完全独立开,新列表的内容完全不受原列表的影响,就需要用深拷贝。
python中深浅拷贝
原文:https://www.cnblogs.com/zylwy/p/14087439.html