a = b似乎是身份,而不是副本。为什么?

时间:2014-01-09 11:56:27

标签: python arrays numpy copy

Hello Python / iPython用户。

我发现使用numpy数组的python有一种奇怪的行为。我自己找到了问题的解决方案,但我很乐意得到解释。提前谢谢。

这是问题所在: 使用ipython我创建了一个numpy数组a和一个名为b:

的副本
import numpy as np
a=np.zeros(5)
b=a

但是,b似乎更像是a的身份而不是副本,因为更改b也会改变a。

b[0]=1
a
array([ 1.,  0.,  0.,  0.,  0.])

解决方案是使用b=a.copy()而不是b=a,但我想理解为什么在python中就是这种情况。我对Matlab,R和Fortran非常熟悉,之前从未碰到这样的问题。为什么有人想要为同一数据创建第二个名称而不是此向量的副本?只是一些特定于python的语法或者还有更多要理解的内容吗?

2 个答案:

答案 0 :(得分:4)

它只是一个python的约定。除了为现有对象创建新句柄外,所有赋值都不会执行任何操作。这是一个非常明智的规则,因为它保持语义简单和透明;在其他语言中,您可能常常想知道您是在修改现有对象,还是创建新对象的句柄。如果你想做一些事情而不是在现有对象上打一个新名字,python总是强迫你明确这个。至于为什么你想要这样做:尝试找到任何一段python代码,并查看它包含多少赋值语句。显然有一个用途;)。

答案 1 :(得分:-1)

这确实是python中某些对象的特殊性。 numpy数组实际上是从python“list”对象派生出来的,它以相同的方式运行。

实际上,当你在python(或numpy数组)中创建一个列表时, 数据存储在存储器中的给定位置。 标识号与此位置相关联,您可以使用“id”函数

查看它
a = [1, 2, 3]
print id(a)

如果键入“b = a”,b将指向与a相同的内存位置。因此a和b将具有相同的 识别号码。

a = [1, 2, 3]
print id(a)
b = a
print id(b)

你必须非常小心,因为对意志的任何修改都会影响b。 “复制”方法将创建a的深层副本,这意味着b存储在新的内存位置

a = numpy.array([1, 2, 3])
print id(a)
b = a
print id(b)
c = a.copy()
print id(c)

现在相当于列表的“复制”,而是必须使用“:”符号

a = [1, 2, 3]
print id(a)
b = a 
print id(b) #a and b are the same
c = a[:]
print id(c) #c is a deep copy of a