天天看点

对于python中赋值操作的小总结直接赋值浅拷贝(copy)深拷贝(deepcopy)

直接赋值

赋值操作是一项非常基本但是重要的操作,在python中,最常见的赋值方式就是直接赋值,比如

b=a

情况1:不可变对象(比如list/tuple/dict)

对于直接赋值而言, 变量b和a都指向同一块内存地址,或者说指向同一个对象。因此对于一个不可变对象而言, 修改a的值等价于修改b。如下

a=[1,2,[3,4]] # 不可变对象
b=a # 直接赋值

a[2].append(5)
a.append(6)

print(f'a={a}')
print(f'b={b}')
           

输出结果

a=[1, 2, [3, 4, 5], 6]
b=[1, 2, [3, 4, 5], 6]
           

情况2:可变对象(单个元素)

但是对于一个可变对象来说,情况又不太一样。比如

a=1

,当进行这样的赋值时,python会在内存中开辟一块地方用来存储这个1,如果我们再通过和上述情况一样的方式进行赋值

b=a

,此时和上面列表的情况一样,变量a和变量b都指向存储1的这块内存地址。但是,当我们对变量a进行修改时,比如

a=2

,这个时候,需要特别注意,python并不是在原先存储1的地方将1修改为2,而是新开辟一块地方用来存储2,也就是说,变量名a指向的内存地址发生了改变!

因此,这个时候变量a和变量b不再指向同一个内存对象,变量b的值与变量a的值并不会相互关联。如下

a=1 #可变对象
b=a 

a=2
print(f'a={a}')
print(f'b={b}')
           

输出结果

a=2
b=1
           

浅拷贝(copy)

还是假设我们有一个原始变量a,通过python内置的

copy

模块,我们可以调用

copy()

方法,创建一个新的变量b。

情况1:不可变对象

我们还是先来考虑不可变对象的情况。比如a对象是一个列表。通过浅拷贝后的b和a是两个独立的对象,但是需要注意,它们的子对象仍然指向同一对象。换句话说,浅拷贝只是单纯拷贝父对象的结构,而不会拷贝内部的子对象,因此它们的子对象依然共享。因此如果修改a的子对象内部的值,那么b会跟着改变。例子如下

import copy

a=[1,2,[3,4]]
b=copy.copy(a) #浅拷贝

a[2].append(5)
a.append(6)

print(f'a={a}')
print(f'b={b}')
           

输出结果

a=[1, 2, [3, 4, 5], 6]
b=[1, 2, [3, 4, 5]]
           

情况2:可变对象

对于可变对象而言,因此不存在内部的子对象,因此浅拷贝会生成一个一个独立的对象。例子如下

import copy

a=1
b=copy.copy(a)

a=2
print(f'a={a}')
print(f'b={b}')
           

输出结果

a=2
b=1
           

深拷贝(deepcopy)

对于这种拷贝,生成的对象b和原始的a是完全独立的两个对象。例子如下

import copy

a=[1,2,[3,4]]
b=copy.deepcopy(a)

a[2].append(5)
a.append(6)

print(f'a={a}')
print(f'b={b}')
           

输出结果

a=[1, 2, [3, 4, 5], 6]
b=[1,2,[3,4]]