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()方法最为安全。