numpy 数组,h[:]=h+1 与 h=h+1
numpy array, h[:]=h+1 vs. h=h+1
好像h[:]=h+1和h=h+1都对h中的所有元素加1。
但是下面可能会发现不同,你能解释一下为什么吗??看起来在第二种情况下,h 不仅作为函数内部变量发生变化,而且还像覆盖全局变量 h...这太令人困惑了...
感谢您的任何输入!
import numpy as np
def fun(h):
h=h+1
return h
h=np.zeros((2,2))+1
hI=h.copy()
for i in range(0,3):
hI = fun(h)
print h
print hI
[[ 1. 1.]
[ 1. 1.]]
[[ 2. 2.]
[ 2. 2.]]
鉴于
import numpy as np
def fun(h):
h[:]=h+1
return h
h=np.zeros((2,2))+1
hI=h.copy()
for i in range(0,3):
hI = fun(h)
print h
print hI
[[ 4. 4.]
[ 4. 4.]]
[[ 4. 4.]
[ 4. 4.]]
这并不奇怪。我认为您对在使用函数 fun
时碰巧将变量命名为 h
这一事实感到困惑。但是该变量的名称并不重要,它是 而不是 到达父作用域来修改变量 h
...相反,传递给 fun
是某物的 名称 ,而不是它的副本。因此 fun
内部的突变仍然会影响被命名的对象(在这种情况下,该对象是全局范围的 h
数组)。
为了更清楚地说明这一点,考虑下面的情况,我所做的只是将 fun
内的变量重命名为 z
而不是 h
...发生相同的结果。
In [14]: def fun(z):
....: z[:] = z + 1
....: return z
....:
In [15]: h = np.zeros((2,2)) + 1
In [16]: for i in range(0, 3):
....: hI = fun(h)
....:
In [17]: print h
[[ 4. 4.]
[ 4. 4.]]
In [18]: print hI
[[ 4. 4.]
[ 4. 4.]]
在第一个例子中,内部变量没有发生变化。分配
h = h + 1
使 local h
(函数范围内的 h
)成为 new 名称,从操作 h + 1
创建的对象的名称,用于之前在该函数范围内由 h
命名的任何事物(例如传入的参数)。
由于 NumPy 数组 h
的广播操作 h + 1
产生了 new 数组,所以语句 h = h + 1
没有变异 h
...仅仅导致名称 h
引用新的东西 (h + 1
).
而在第二个例子中,
h[:] = h + 1
就是说h
命名的任何对象的内容都更新了。
你可以像我一样叫它z[:]
,没关系。左侧的 "thing[:]" 是切片赋值的表示法,它是为 NumPy 数组实现的,作为切片对象数据的变异。
这个
def fun(h):
h=h+1
return h
复制输入参数h
。所以输入 h
永远不会改变,即使变量名称恰好相同(您可以使用 f = h + 1; return f
甚至 return h + 1
;所有内容都相同)。当您将输入 h
分配给新的 h
时,您只是失去了对输入 h
的引用。
由于输入 h
恰好是您的原始 h
(全为 1),因此原始永远不会改变,这就是您在输出中看到的。
您每次都将 1 添加到原件(在对 fun
的三次调用中),但是由于原件永远不会改变,它始终是一个 2 的数组。
这个
def fun(h):
h[:]=h+1
return h
确实改变了输入 h
。您通过 [:]
更改它 "in place"。所以在这种情况下,返回的 h
与输入 h
相同,这就是为什么您会在输出中看到两次相同的 2x2 数组。
因为你 运行 这个函数三次,所以它被加了三次 1,结果都是 4。
区别在于 =
语句的解释。都是 there :
案例h=h+1
:
If the target is an identifier (name): the name is bound to the object in the current local namespace.
案例h[:]=h+1
:
If the target is a subscription: The primary expression in the reference is evaluated,and the sequence is asked to assign the assigned object to its item with that index.
好像h[:]=h+1和h=h+1都对h中的所有元素加1。
但是下面可能会发现不同,你能解释一下为什么吗??看起来在第二种情况下,h 不仅作为函数内部变量发生变化,而且还像覆盖全局变量 h...这太令人困惑了... 感谢您的任何输入!
import numpy as np
def fun(h):
h=h+1
return h
h=np.zeros((2,2))+1
hI=h.copy()
for i in range(0,3):
hI = fun(h)
print h
print hI
[[ 1. 1.]
[ 1. 1.]]
[[ 2. 2.]
[ 2. 2.]]
鉴于
import numpy as np
def fun(h):
h[:]=h+1
return h
h=np.zeros((2,2))+1
hI=h.copy()
for i in range(0,3):
hI = fun(h)
print h
print hI
[[ 4. 4.]
[ 4. 4.]]
[[ 4. 4.]
[ 4. 4.]]
这并不奇怪。我认为您对在使用函数 fun
时碰巧将变量命名为 h
这一事实感到困惑。但是该变量的名称并不重要,它是 而不是 到达父作用域来修改变量 h
...相反,传递给 fun
是某物的 名称 ,而不是它的副本。因此 fun
内部的突变仍然会影响被命名的对象(在这种情况下,该对象是全局范围的 h
数组)。
为了更清楚地说明这一点,考虑下面的情况,我所做的只是将 fun
内的变量重命名为 z
而不是 h
...发生相同的结果。
In [14]: def fun(z):
....: z[:] = z + 1
....: return z
....:
In [15]: h = np.zeros((2,2)) + 1
In [16]: for i in range(0, 3):
....: hI = fun(h)
....:
In [17]: print h
[[ 4. 4.]
[ 4. 4.]]
In [18]: print hI
[[ 4. 4.]
[ 4. 4.]]
在第一个例子中,内部变量没有发生变化。分配
h = h + 1
使 local h
(函数范围内的 h
)成为 new 名称,从操作 h + 1
创建的对象的名称,用于之前在该函数范围内由 h
命名的任何事物(例如传入的参数)。
由于 NumPy 数组 h
的广播操作 h + 1
产生了 new 数组,所以语句 h = h + 1
没有变异 h
...仅仅导致名称 h
引用新的东西 (h + 1
).
而在第二个例子中,
h[:] = h + 1
就是说h
命名的任何对象的内容都更新了。
你可以像我一样叫它z[:]
,没关系。左侧的 "thing[:]" 是切片赋值的表示法,它是为 NumPy 数组实现的,作为切片对象数据的变异。
这个
def fun(h):
h=h+1
return h
复制输入参数h
。所以输入 h
永远不会改变,即使变量名称恰好相同(您可以使用 f = h + 1; return f
甚至 return h + 1
;所有内容都相同)。当您将输入 h
分配给新的 h
时,您只是失去了对输入 h
的引用。
由于输入 h
恰好是您的原始 h
(全为 1),因此原始永远不会改变,这就是您在输出中看到的。
您每次都将 1 添加到原件(在对 fun
的三次调用中),但是由于原件永远不会改变,它始终是一个 2 的数组。
这个
def fun(h):
h[:]=h+1
return h
确实改变了输入 h
。您通过 [:]
更改它 "in place"。所以在这种情况下,返回的 h
与输入 h
相同,这就是为什么您会在输出中看到两次相同的 2x2 数组。
因为你 运行 这个函数三次,所以它被加了三次 1,结果都是 4。
区别在于 =
语句的解释。都是 there :
案例h=h+1
:
If the target is an identifier (name): the name is bound to the object in the current local namespace.
案例h[:]=h+1
:
If the target is a subscription: The primary expression in the reference is evaluated,and the sequence is asked to assign the assigned object to its item with that index.