为什么python/numpy的+=会改变原始数组?

2024-04-27 02:33:10 发布

您现在位置:Python中文网/ 问答频道 /正文

import numpy as np

W = np.array([0,1,2])
W1 = W
W1 += np.array([2,3,4])
print W

W = np.array([0,1,2])
W1 = W
W1 = W1 + np.array([2,3,4])
print W

上面的代码将变异W,但是下面的代码不会变异W。为什么?


Tags: 代码importnumpyasnparrayw1print
3条回答

本质上,++=是任何类都可以实现的不同方法。在numpy中,+=被实现为在内存中进行更改,而+返回一个新数组。

更多细节请参见this question

在这种情况下

W = np.array([0,1,2])
W1 = W
W1 += np.array([2,3,4])

W指向内存中的某个位置,其中包含一个numpy数组。W1指向同一位置。W1 += np.array([2,3,4])获取内存中的那个位置,并更改内容。

在这种情况下:

W = np.array([0,1,2])
W1 = W
W1 = W1 + np.array([2,3,4])

WW1开始指向内存中的相同位置。然后创建一个新数组(W1 + np.array([2,3,4])),该数组位于内存中的新位置。(请记住:总是首先计算右侧,然后才将其分配给左侧的变量。)然后,使W1指向内存中的这个新位置(通过将W1分配给这个新数组)。W仍然指向内存中的旧位置。从现在起,WW1不再是同一个数组。

这几乎适用于任何类型的收藏。这仅仅是因为python处理变量的方式。var1 += var2与集合中的var1 = var1 + var2不同。我会尽我所能解释它,这肯定是可以改进的,所以任何编辑/批评都是受欢迎的。

print("1:")
x1 = [7]
y1 = x1
y1 += [3]
print("{} {}".format(x1, id(x1)))
print("{} {}".format(y1, id(y1)))

print("2:")
x2 = [7]
y2 = x2
y2 = y2 + [3]
print("{} {}".format(x2, id(x2)))
print("{} {}".format(y2, id(y2)))

输出:

1:
[7, 3] 40229784 # first id
[7, 3] 40229784 # same id
2:
[7]    40228744 # first id
[7, 3] 40230144 # new id

var1 = var1 + var2将创建一个新的ID为的新对象。它接受旧值,将其添加到第二个变量中,并将其分配给具有第一个对象名称的新对象。在var1 += var2示例中,它只是将它附加到ID指向的对象,该ID与旧变量相同。

相关问题 更多 >