Python numpy自我分裂的意外行为

Python numpy自我分裂的意外行为,python,numpy,division,Python,Numpy,Division,这种行为对我来说有点奇怪,我一直认为x/=5。相当于x=x/5。但是很明显,g(x)函数并没有用/=操作创建一个新的引用。有人能解释一下吗 我一直认为x/=5。相当于x=x/5 它是,除非类重写\uu idiv\uu操作符,就像numpy.ndarray那样。 numpy.ndarray重写它以就地修改数组,这很好,因为它避免了在不需要复制时创建数组的新副本。正如您所猜测的,它还覆盖了其余的\uu i*\uu操作符。Python的就地操作符允许操作修改等式左侧的对象,而不是创建新的对象。您将在l

这种行为对我来说有点奇怪,我一直认为x/=5。相当于x=x/5。但是很明显,g(x)函数并没有用/=操作创建一个新的引用。有人能解释一下吗

我一直认为x/=5。相当于x=x/5

它是,除非类重写
\uu idiv\uu
操作符,就像
numpy.ndarray
那样。
numpy.ndarray
重写它以就地修改数组,这很好,因为它避免了在不需要复制时创建数组的新副本。正如您所猜测的,它还覆盖了其余的
\uu i*\uu
操作符。

Python的就地操作符允许操作修改等式左侧的对象,而不是创建新的对象。您将在
list
s和其他内置可变类型中看到相同的行为:

def f(x):
    x=x/5.
    return x
def g(x):
    x/=5.
    return x

x_var = np.arange(5,dtype=np.double)
f(x_var)
print x_var
g(x_var)
print x_var

Output:
[ 0.  1.  2.  3.  4.]
[ 0.   0.2  0.4  0.6  0.8]
所以这是预期的行为

当然,在处理不可变类型时,会创建一个新对象,因为现有对象无法修改

我一直认为x/=5。相当于x=x/5

事实并非如此。当您执行
x=x/5.
时,实际上您正在发动机罩下执行两个单独的操作:

x = []
y = x
x += [1]
print y   # prints [1] because x still refers to the same object as y
x = x + [2]
print x   # prints [1, 2] for obvious reasons
print y   # prints [1] again because x has been rebound to a new list
          # while y still refers to the original one
而当您使用
/=
操作符时,您明确地要求Python在不创建临时对象的情况下修改对象
x
。如其他答案中所述,
/
操作符调用对象(如果有)的
\uuu div\uuu
方法,而
/=
调用其
\uu idiv\uu
方法


如果要修改的对象很大,就地修改非常有用:无需创建同样大的临时对象。然而,如果你不小心,它会咬你。特别是,让函数在没有警告的情况下修改其输入参数通常不是一个好主意…

感谢您的解释,我找不到导致我预期这种行为的文档。这不是numpy问题,而是通过引用传递对象的问题。所有
\uuu i*\uu
的默认实现是就地执行操作。如果可能,请阅读。将Python列表传递给定义f(a)的函数也会遇到同样的问题:a*=3;返回一个,它将修改您调用它的原始对象,而不是简单地返回一个修改后的副本。谢谢,这是我正在寻找的文档参考。因此,如果可能,应在适当位置执行操作。如果i*不可用,它将默认为正常*操作。
temporary = x/5.
x = temporary