034 Python深浅拷贝

一、引言

在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的内存地址都不相同,并且其中的可变类型的内存地址也不相同。

这表示,这两个变量没有任何关联,只是单纯的值拷贝,不会影响彼此

原文地址:https://www.cnblogs.com/XuChengNotes/p/11309574.html