Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected behavior for numpy self division

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]

This behavior is a little bit strange to me, I always thought x/=5. was equivalent to x=x/5. . But clearly the g(x) function does not create a new reference with /= operation. Could anyone offer an explanation for this?

like image 989
bluecat Avatar asked Apr 09 '13 16:04

bluecat


2 Answers

I always thought x/=5. was equivalent to x=x/5

It is, unless the class overrides the __idiv__ operator, like numpy.ndarray does. numpy.ndarray overrides it to modify the array in-place, which is good because it avoids creating a new copy of the array, when copying is not required. As you can guess, it also overrides the rest of the __i*__ operators.

like image 136
shx2 Avatar answered Nov 11 '22 21:11

shx2


Python's in-place operators allow the operation to modify the object on the left side of the equation rather than creating a new one. You'll see the same behavior with lists and other built-in mutable types:

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

So this is expected behavior.

When dealing with immutable types, of course, a new object is created, because the existing one can't be modified.

like image 41
kindall Avatar answered Nov 11 '22 21:11

kindall