Subtleties in Python and numpy assignment and argument passing

In [9]:
a = 555
b = a
print(id(a),id(b))
a = 77  # a now re-pointed at some other address in memory
b
print(id(a),id(b))
140542964912560 140542964912560
9787328 140542964912560
In [3]:
import numpy as np
a = np.ones(3)
b = a
a[2] = 999
b
Out[3]:
array([  1.,   1., 999.])
In [4]:
# id() gives you the memory address 
id(a), id(b)
Out[4]:
(140543212159904, 140543212159904)

How to keep the original values in b?

In [10]:
a = np.ones(3)
b = a.copy()
a[2] = 999
b
Out[10]:
array([1., 1., 1.])
In [12]:
a = np.ones(3)
b = np.array(a)
a[2] = 999
b, id(a), id(b)
Out[12]:
(array([1., 1., 1.]), 140542964975936, 140543212655120)
In [ ]:
Another context - function calls
In [13]:
def foo(a,x):
    a[0] = 999
    x = 777
    
p = np.zeros(4,dtype=int)
q = 3
foo(p,q)
p,q
Out[13]:
(array([999,   0,   0,   0]), 3)
In [16]:
# difference between += and =
# y += s    # updates in place
# y = y + s # creates value y+s in a new memory location and re-points y at it

# they are not the same

y = np.ones(3,dtype=int)
z = y
y += 100
z, id(y),id(z)
Out[16]:
(array([101, 101, 101]), 140542965011120, 140542965011120)
In [17]:
y = np.ones(3,dtype=int)
z = y
y = y + 100
z, id(y),id(z)
Out[17]:
(array([1, 1, 1]), 140542964936176, 140542965011760)
In [ ]: