python函数修改调用范围内的变量

标签 python function numpy

谁能解释一下为什么fun1不修改变量y的值,而fun2却修改?我需要逐行修改数组,但同时更新 y 并不是我正在寻找的行为。

def fun1(x):
    x = 2*x
    return x


def fun2(x):
    for i in range(0, x.shape[0]):
        x[i, :] = 2*x[i, :]
    return x


y = np.random.uniform(0, 100, (10, 10))

z1 = fun1(y)
print(np.array(z1 == y).all())
# False

z2 = fun2(y)
print(np.array(z2 == y).all())
# True

最佳答案

修改您的函数以显示 id对象的数量

def fun1(x):
    print(id(x),id(y))
    x = 2*x
    print(id(x))
    return x

In [315]: y = np.arange(3)
In [316]: id(y)
Out[316]: 140296824014768
In [317]: z = fun1(y)
140296824014768 140296824014768    
140296823720096
In [318]: id(z)
Out[318]: 140296823720096

所以 y 引用的数组被传递给函数,并且可以被 x 引用(参数变量)和 y (外部变量)。但分配改变了 x引用 - 该对象被传回 zy没有变化。

def fun2(x):
    print(id(x), id(y))
    x[0] = 23
    print(id(x))
    return x

使用第二个函数,赋值会更改 x 的元素,但不会更改 id所引用对象的。 y , xz全部引用相同的数组。

In [320]: y
Out[320]: array([0, 1, 2])
In [321]: id(y)
Out[321]: 140296824014768
In [322]: z = fun2(y)
140296824014768 140296824014768
140296824014768
In [323]: id(z)
Out[323]: 140296824014768
In [324]: z
Out[324]: array([23,  1,  2])
In [325]: y
Out[325]: array([23,  1,  2])

如果我们复制 y ,或者在将其传递给函数之前,或者在函数内部,然后修改 x不会修改y .

In [327]: y = np.arange(3)
In [328]: id(y)
Out[328]: 140296823645328
In [329]: z = fun2(y.copy())
140296823647968 140296823645328
140296823647968
In [330]: id(z)
Out[330]: 140296823647968
In [331]: z
Out[331]: array([23,  1,  2])
In [333]: y
Out[333]: array([0, 1, 2])

我们将数组传递给函数这一事实并没有改变对副本的需求。即使我们只是在顶层执行操作,我们也会得到相同的行为。

In [334]: y = np.arange(3)
In [335]: x = y.copy()
In [336]: x[:2]=22
In [337]: x
Out[337]: array([22, 22,  2])
In [338]: y
Out[338]: array([0, 1, 2])
<小时/>

如果对象是列表,我们会得到相同的行为:

In [339]: yl = [1,2,3]
In [340]: fun1(yl)
140296925836360 ...
140296824729096
Out[340]: [1, 2, 3, 1, 2, 3]

In [341]: fun2(yl)
140296925836360 ...
140296925836360
Out[341]: [23, 2, 3]
In [343]: yl
Out[343]: [23, 2, 3]

关于python函数修改调用范围内的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51195343/

相关文章:

python - 如何更新通过 "OneToOneField"扩展的用户模型

来自单独文件+位置的 python doctest

python - 计算 AUC 曲线时如何创建阈值?

javascript - 函数内的重叠循环

python - 根据阈值减少列表中元组的数量

python - python 的加/减运算符±

python - 如何实现基于动量的随机梯度下降 (SGD)

JavaScript 定义然后调用语法

ios - 代码;如何从另一个 ViewController 调用 AppDelegate 中的函数

Python3 - 矩阵和数组之间计算高效的相关性