一文看懂python的深拷贝、浅拷贝

之前也学习过深复制、浅复制,但在实际应用的时候还是会遇到一些问题。也看过一些相关的文章,但很久也没太搞明白。今天特意在做一个二维列表的复制的时候遇到了问题,再研究一些文章再实验后,终于明白了深浅复制的根本。写出来自用,也可以给需要的人一些帮助。

理解和记住什么是可变数据什么是不可变数据非常重要:

不可变数据(3个)Number(数字)、String(字符串)Tuple(元组)

可变数据(3个):List(列表)Dictionary(字典)Set(集合)

不可变数据和可变数据是浅拷贝的根本,这两个概念分不清,就无法理解浅拷贝的问题。

 

浅拷贝:浅拷贝仅仅是地址指向,不会开辟新空间(仅仅是最顶层开辟了新的空间,里层的元素地址还是一样的。注1)浅拷贝时,改变原始或拷贝对象的可变数据时,原始和拷贝对象的值都变化,改变不可变数据时,只有改变的值变化,原值不变。

注1:仅仅是最顶层开辟了新的空间,里层的元素地址还是一样的。原始和拷贝的id是不同的,但里面元素的id是相同的。例:

#定义一个列表
a=[[1,2],'a',2  ]#第一个元素是可变的,第二、三是是不可变的
b=a[:]#进行浅拷贝
print(id(a),id(b)) #查询对象地址
#地址不同
1519791594760 1519791594440

#查询第一个元素地址是否相同
print(id(a[0]),id(b[0]))
#地址相同
1519791595080 1519791595080

#查询第二个元素地址是否相同
print(id(a[1]),id(b[1]))
#地址相同
1519784151112 1519784151112

改变原始或拷贝对象的可变数据时,原始和拷贝对象的值都变化,续上例:

#改变第一个元素值
a[0][0]=2
print(b)
#b的值发生了相同的变化(因为[2,2]是列表是可变数据)
[[2, 2], 'a', 2]

#改变第二个元素的值
a[1]='c'
#b的值不变。(因为‘a’为字串是不可变数据。)
[[2, 2], 'a', 2]

浅拷贝的5种方法:

1.切片浅拷贝(常用):

a=[1,2,4]

b=a[:]

2. 模块copy浅拷贝

import copy

a=[1,2,4]

b=copy.copy(a)

3.利用list()函数浅拷贝

a=[1,2,4]

b=list(a)

4.列表方法extend浅拷贝

a=[1,2,4]

b=[]

b.extend(a)

5.列表推导浅拷贝

a=[1,2,4]

b=[x for x in a]

深拷贝:真正意义的复制,原始和拷贝数据互不影响。方法也只有一种。利用copy模块中的deepcopy进行深拷贝。例:

import copy

a=[[1,2],3,4]

b=copy.copy(a)

总结:对于浅拷贝,原数据为可变的拷贝后也可变,原数据和拷贝数据互相影响。原数据为不可变,拷贝后也不可变,即原数据和拷贝数据互不影响,即:“变变不变不变”。深拷贝就互相不影响。

猜你喜欢

转载自blog.csdn.net/kim5659/article/details/108683444