目录
-
一、引言
- 1.1 可变 or 不可变
- 二、拷贝
- 三、浅拷贝
- 三、深拷贝
一、引言
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
针对该列表
l1=['a','b','c',['d','e','f']]
一般有三种方法,分别为:拷贝(赋值)、浅拷贝、深拷贝
注意: 拷贝 / 浅拷贝 / 深拷贝 都是针对可变类型数据而言的
1.1 可变 or 不可变
id不变值可变,即在原值的基础上修改,则为可变数据类型;值变id也变,即重新申请一个空间放入新值,则为不可变数据类型。
可变or不可变 | 数据类型 |
---|---|
可变 | 列表,字典,集合 |
不可变 | 数字,字符串,元组 |
二、拷贝
当lt2为lt的拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化
简单的赋值,既两个变量指向同一个内存地址
lt = [1,2,3,[1,2,3]]
lt1 = lt
lt.append(1)
print(lt,id(lt))
for i in lt1:
print(i,id(i))
print()
print(lt1,id(lt1))
for i in lt:
print(i,id(i))
[1, 2, 3, [1, 2, 3], 1] 2625145561800
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3] 2625145561736
1 140720359563920
[1, 2, 3, [1, 2, 3], 1] 2625145561800
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3] 2625145561736
1 140720359563920
上述打印内容会发现,可变类型lt和lt1的地址相同。
lt中的可变类型lt[-1]和lt1的可变类型lt1[-1]的地址也相同。
三、浅拷贝
浅拷贝:当lt2为lt的浅拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2不变化
copy.copy() 可变数据的类型中的内置方法.copy()也是浅拷贝
import copy
lt = [1,2,3,[1,2,3]]
lt1 = copy.copy(lt)
lt[-1].append(1)
lt.append(1)
print(lt,id(lt))
for i in lt1:
print(i,id(i))
print()
print(lt1,id(lt1))
for i in lt:
print(i,id(i))
[1, 2, 3, [1, 2, 3, 1], 1] 1730037789896
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3, 1] 1730319865992
[1, 2, 3, [1, 2, 3, 1]] 1730319793928
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3, 1] 1730319865992
1 140720359563920
上述打印内容会发现,可变类型lt和lt1的地址并不相同。这代表这两个列表有着各自的内存空间
但是可变类型lt和lt1中的可变类型,又有着相同的内存地址,表面他们指向同一块内存。
既,更改lt中的可变类型lt[-1]内容,同样会影响lt1[-1]内容
三、深拷贝
深拷贝: 当lt2为lt的深拷贝对象时,lt内的可变类型变化,lt2不变化;lt内的不可变类型变化,lt2不变
copy.deepcopy() 我个人理解,深拷贝就是值拷贝
import copy
lt = [1,2,3,[1,2,3]]
lt1 = copy.deepcopy(lt)
lt[-1].append(1)
lt.append(1)
print(lt,id(lt))
for i in lt1:
print(i,id(i))
print()
print(lt1,id(lt1))
for i in lt:
print(i,id(i))
[1, 2, 3, [1, 2, 3, 1], 1] 1581432267400
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3] 1581461734280
[1, 2, 3, [1, 2, 3]] 1581461779656
1 140720359563920
2 140720359563952
3 140720359563984
[1, 2, 3, 1] 1581432267464
1 140720359563920
上述打印内容会发现,无论是lt还是lt1的内存地址都不相同,并且其中的可变类型的内存地址也不相同。
这表示,这两个变量没有任何关联,只是单纯的值拷贝,不会影响彼此