为什么我明确需要.copy()一个numpy数组/列表?

时间:2018-05-03 08:11:21

标签: python arrays list numpy copying

为什么我需要.copy()一个numpy数组(或列表,虽然那些没有.copy()但是为了一个很好的最小例子),当我想得到它的独立副本时,虽然我不必用变量这样做? 这种行为的原因是什么?

E.g。设置a = 1b = a,然后设置b = 2不会更改a,而a=([0])b = ab[0]=1也会更改{ {1}}。

修改

这似乎是一个非常常见的问题/问题,可以通过各种方式提出,所以我找不到它。快速“我只需要了解发生了什么,以便我可以继续前进”我想答案(以及其他相同/类似问题的答案)已经足够了。为了更好地理解,我猜@chthonicdaemon在评论中提供的this链接对我来说似乎是一个很好的起点。

更长的背景

在许多情况下,我必须设置一个带有一些起始值的numpy数组,然后在我的程序运行时填充其他值。即。

a

你明白了。

但是为了能够将结果与它进行比较,通常需要保留基础数组,所以我先设置基数然后从中复制。所以我希望我能像这样设置它:

logger = np.zeros(5)
#various things happen
logger[0] = 1
#more stuff happens
logger[3] = 1

这样

base = np.zeros(5)
logger = base
logger[0] = 1

然而,使用上面的数组,它们保持“连接”,所以我得到

In [1]:base
Out[1]:array([ 0.,  0.,  0.,  0.,  0.])
In [2]:logger
Out[2]:array([ 1.,  0.,  0.,  0.,  0.])

我可以通过明确使用

来解决这个问题
In [1]:base
Out[1]:array([ 1.,  0.,  0.,  0.,  0.])

但我想知道为什么要这么做。

1 个答案:

答案 0 :(得分:1)

列表(和numpy数组)是 mutuable 对象。 str和int 不可变。不可变对象一旦创建就无法更改,因此:

a = 1
b = a

两者都指向int的不可变对象,值为1.当您更改b时,为其分配一个新值:

b = 3

现在b指向另一个对象,而a指针没有变化。

现在,列表是可变的。这意味着,您可以在创建后更改这些对象。

alist = list((1, 2, 3))
newlist = alist

alist == newlist
True

alist现在是对列表对象的引用。列表对象只是对实际对象的引用的容器。因此,当我为alist赋值新变量时,我只创建另一个指向同一容器对象的变量。

操纵一个对象会影响两个变量,因为它们引用同一个容器对象。

副本的作用是制作列表的新副本,包括参考文献的副本。 (有时称为深度复制)。这会创建一个新的容器对象,因此在更改其中一个列表时 - 另一个不会更改。