如果我有一个列表x = [1, 2, 3]
并将其传递给使用f
形式的运算符+=
的函数f(x[:])
,则会生成一个浅表副本并且内容为没有改变:
def f(x):
print "f, x = ", x, ", id(x) = ", id(x)
x += [1]
print "f, x = ", x, ", id(x) = ", id(x)
x = [1,2,3]
print "x = ", x, ", id(x) = ", id(x)
f(x[:])
print "x = ", x, ", id(x) = ", id(x)
输出:
x = [1, 2, 3] , id(x) = 139701418688384
f, x = [1, 2, 3] , id(x) = 139701418790136
f, x = [1, 2, 3, 1] , id(x) = 139701418790136
x = [1, 2, 3] , id(x) = 139701418688384
然而,期待ndarray
x = np.array([1, 2, 3])
的相同行为我对内容发生了变化感到惊讶,即使确实制作了副本:
import numpy as np
def f(x):
print "f, x = ", x, ", id(x) = ", id(x)
x += [1]
print "f, x = ", x, ", id(x) = ", id(x)
x = np.array([1,2,3])
print "x = ", x, ", id(x) = ", id(x)
f(x[:])
print "x = ", x, ", id(x) = ", id(x)
输出:
x = [1 2 3] , id(x) = 139701418284416
f, x = [1 2 3] , id(x) = 139701418325856
f, x = [2 3 4] , id(x) = 139701418325856
x = [2 3 4] , id(x) = 139701418284416
(我知道+[1]
函数对于ndarray和列表的行为不同。如何传递像列表一样的ndarray并避免这种行为?
加分问题为什么在函数x = x + [1]
中使用f
解决了问题?
答案 0 :(得分:2)
如果您想要副本,可以使用numpy-array的copy
方法:
f(x.copy())
请注意,即使id
和x
的{{1}}不同,这些数组也可能共享相同的内存,因此对一个内容的更改将传播到另一个反之亦然:
x[:]
但通常情况下,您不会将副本传递给某个功能。您可以在函数中创建一个副本:
x = np.array([1,2,3])
y = x[:]
np.may_share_memory(x, y) # True
z = x.copy()
np.may_share_memory(x, z) # False