为什么我需要.copy()
一个numpy数组(或列表,虽然那些没有.copy()
但是为了一个很好的最小例子),当我想得到它的独立副本时,虽然我不必用变量这样做? 这种行为的原因是什么?
E.g。设置a = 1
和b = a
,然后设置b = 2
不会更改a
,而a=([0])
,b = a
和b[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.])
但我想知道为什么要这么做。
答案 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
赋值新变量时,我只创建另一个指向同一容器对象的变量。
操纵一个对象会影响两个变量,因为它们引用同一个容器对象。
副本的作用是制作列表的新副本,包括参考文献的副本。 (有时称为深度复制)。这会创建一个新的容器对象,因此在更改其中一个列表时 - 另一个不会更改。