python copy.deepcopy()深入解读

copy.deepcopy()的用法是将某一个变量的值赋值给另一个变量(此时两个变量地址不同),因为地址不同,所以可以防止变量间相互干扰。

大家可以猜猜下面代码第四行输出什么值
例1.

a = [1, 2, 3]
d = a # a和d的地址相同, 看第5行的输出
a[0] = 2 
print(d)
print(id(a), id(b)) # id() 输出a和d变量的地址

答案是:[2 2 3]

[2, 2, 3]
2063948923080 2063948923080

原因是通过赋值的方式使得d和a的地址相同,即d和a指向内存中的同一个地址。
而且改变d中的值,a也会随着改变,自己可以尝试一下。

如果想让a和d两个变量互不影响,就用copy.deepcopy()函数
例2.

import copy
a = [1, 2, 3]
d = copy.deepcopy(a) # a和d的地址不相同
a[0] = 2
print(d)
print(id(a), id(d))

输出:

[1, 2, 3]
2793378037960 2793379617288

思考下面代码会输出什么:
例3.

a = [1, 2, 3]
d = a 
c = 1 # 注意 1其实也有地址,而且这个地址是固定的,不会随程序发生改变。
a = c
print(d)

如果你有点绕不开了,先看看答案吧。
答案是:

[1, 2, 3]

也许你奇怪a和d的地址不是一样的吗,怎么改变了a,d还是不变了。原因很简单,因为c的地址和a的地址不同,把c赋值给a,则a的地址和c的地址相同,但d的地址在初始时就已经是a原先的地址了。即使a的地址后来发生了变化,d的地址也不受影响。

通过以上的介绍你可能会认为只要两个变量的地址不同,则两者之间不会相互影响,否则就会。真的是这样吗?

上面的例子比较简单,可以这么认为。再补充几个例子,看看程序的输出与自己想象的结果是否一样:
例4.

import numpy as np
a = np.array([[1,2,3], [5,5,5]])
d = a.transpose(1,0)
print(id(d), id(a)) # a和d的地址不同,但d会受a的影响,当然a也会受d影响
a[0, 0] = 9
print(d)

输出:

2129658874816 2129658874576
[[9 5]
 [2 5]
 [3 5]]

例5

import numpy as np
a = np.array([1, 2, 3])
b = np.array([1, 5, 6])
c = np.array([a, b])
print(id(a), id(c), id(c[0])) # 虽然c[0]值等于a,但c[0]和a的地址不同
a[0] = 9
print(c)

输出:

2204876507856 2204879229216 2204879229296
[[1 2 3]
 [1 5 6]]

例6

import numpy as np
a = np.array([1, 2, 3])
b = np.array([1, 5, 6])
c = a - b
a[0] = 9
print(c)

输出:

[ 0 -3 -3]

例7.

import numpy as np
c = np.array([[3, 2, 3], [5, 7, 8]])
e = c[0]
e[0] = 9
print(c)
print(id(e), id(c[0]), id(c[1]), id(c)) # e和c的地址不同,但和c[0]相同

输出:

[[9 2 3]
 [5 7 8]]
1965873400768 1965876121968 1965876121968 1965873400528

总结:①从例5,6可以看出,如果一个变量由多个变量通过某种方式(拼接或加减)得来的,则这个变量不会受其他变量的影响。但结合例7,如果一个变量e来自另一个变量c的某一部分值,则改变量e的值(不改变e的地址时),变量c也会受影响。②从例4可知,虽然两个变量a,d地址不同,但d是通过a经过自身变换(转置,只改变形状)而来,所以改变某一个变量内的值,另一个变量也会跟着改变。所以说并不能单纯地认为变量地址不同,变量间就不会相互影响。所以为了防止变量间相互影响,使用copy.deepcopy()方法最为安全。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值