【问题标题】:Modifying a numpy array inside a function?修改函数内的numpy数组?
【发布时间】:2013-02-18 17:43:18
【问题描述】:

我对下面的简单程序有疑问:

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 是通过复制而不是通过函数内部的引用传递的。如何纠正?

【问题讨论】:

    标签: python arrays numpy pass-by-reference


    【解决方案1】:

    np.zeros(0) 给你一个空的 numpy 数组。您的函数中的引用现在指向一个新的 Python 列表,但您实际上并没有修改您的空 numpy 数组,所以这仍然是您要打印的内容。

    推荐阅读this answer来理清一些概念。

    【讨论】:

    【解决方案2】:

    引用传递模型更像是指针的值传递。因此,在您的 my_function 中,您有一个指向原始 my_array 的指针的副本。如果您要使用该指针直接操作输入的数组,则会进行更改,但复制指针的重新分配不会影响原始数组。

    举个例子:

    def my_func(a):
        a[1] = 2.0
    
    ar = np.zeros(4)
    my_func(ar)
    print ar
    

    上面的代码会改变ar的内部值

    【讨论】:

      【解决方案3】:

      您可以在这里使用切片分配,就像使用列表一样:

      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 时,您将引用绑定到名称my_array 的原始ndarray 对象。但是,一旦您为该名称​​分配新内容,您就会丢失原始引用并将其替换为对新对象(在本例中为列表)的引用。

      请注意,具有可变对象的默认参数通常可以lead to surprises

      【讨论】:

      • 我想知道是否有一种巧妙的方法可以避免:3。如果输入数组有十个元素,那么这段代码不会像我怀疑 OP 对他的代码所期望的那样。
      • 这实际上不起作用 - 尝试 a = np.zeros(0)a[:3] = [1,2,3]
      • @MrE -- 当然。我想我假设 OP 实际上会传入一个足够大的参数来处理计算中的 RHS。
      猜你喜欢
      • 2021-09-24
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多