在函数内修改numpy数组?
我遇到了一个简单程序的问题,如下所示:
def my_function(my_array = np.zeros(0)):
my_array = [1, 2, 3]
my_array = np.zeros(0)
my_function(my_array)
print my_array
这个程序打印出来的是一个空数组,就好像在函数里面传递的my_array
是复制过来的,而不是引用。请问怎么才能修正这个问题呢?
3 个回答
9
你可以像处理列表一样使用切片赋值:
def func(my_array):
my_array[:3] = [1,2,3]
注意,这里要求 my_array
至少要有 3 个元素……下面是一个使用示例:
>>> def func(my_array):
... my_array[:3] = [1,2,3]
...
>>> a = np.zeros(4)
>>> a
array([ 0., 0., 0., 0.])
>>> func(a)
>>> a
array([ 1., 2., 3., 0.])
你缺少的一个点是 Python 如何处理引用。当你进入 my_function
时,你有一个指向原始 ndarray 对象的引用,这个对象绑定在 my_array
这个名字上。但是,一旦你给这个名字 赋值 新的内容,你就会失去对原始对象的引用,而是用一个新对象(在这个例子中是一个列表)的引用替代它。
注意,使用一个可变对象作为默认参数,常常会 导致一些意外情况
17
传递引用的模型其实更像是传递一个指针的值。也就是说,在你的 my_function 函数里面,你拿到的是指向原始 my_array 的一个指针的副本。如果你用这个指针直接去修改输入的数组,那确实会改变原来的数组,但如果你只是重新给这个副本的指针赋值,那就不会影响到原来的数组。
举个例子:
def my_func(a):
a[1] = 2.0
ar = np.zeros(4)
my_func(ar)
print ar
上面的代码会改变 ar 的内部值。
6
np.zeros(0)
会给你一个空的 numpy 数组。在你的函数里面,引用现在指向了一个新的 Python 列表,但你实际上并没有修改你那个空的 numpy 数组,所以你打印出来的还是那个空数组。
建议你阅读 这个回答 来澄清一些概念。