在函数内修改numpy数组?

6 投票
3 回答
27631 浏览
提问于 2025-04-17 17:52

我遇到了一个简单程序的问题,如下所示:

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 数组,所以你打印出来的还是那个空数组。

建议你阅读 这个回答 来澄清一些概念。

撰写回答