2

I am confused by the mutable variable in python. See the following example code:

In [144]: a=[1,2,3,4]

In [145]: b=a

In [146]: a.append(5)

In [147]: a
Out[147]: [1, 2, 3, 4, 5]

In [148]: b
Out[148]: [1, 2, 3, 4, 5]

Since list is mutable, when using append function, it works on the same memory. This is understandable to me. But the following code confuses me.

In [149]: import numpy as np

In [150]: a=np.random.randn(3,2)

In [151]: b=a

In [152]: a=a-1

In [153]: a
Out[153]:
array([[-2.05342905, -1.21441195],
       [-1.29901352, -3.29416381],
       [-2.28775209, -1.65702149]])

In [154]: b
Out[154]:
array([[-1.05342905, -0.21441195],
       [-0.29901352, -2.29416381],
       [-1.28775209, -0.65702149]])

Since the Numpy array variable is also mutable, when a=a-1, why the change didn't be made on the same memory that a refers to? On the other hand, a refers to a new memory with new values.
Why variable a didn't act similarly in the first example about appending a new value 5 in the list, a still refers to the same memory?

storen
  • 1,025
  • 10
  • 22

2 Answers2

2

Because when you call a=a-1 you are assigning a new value to variable a... then the whole memory allocation to this variable is changed since a-1 isn't changing a in-place, and instead creates another object..

a = [1,2,3] 
b = a
a = a + [4]
a 
>>> [1,2,3,4] 
b
>>> [1,2,3]

See? It has nothing to do with numpy specificly...

adir abargil
  • 5,495
  • 3
  • 19
  • 29
1

Short answer: a -= 1 is inplace but a = a-1 copies memory of a to another place and then subtracts 1. Therefore, the location where a originally pointed, changes.

You can check this using is. The is keyword says if two variables refer to the same object in memory or not, it is different from ==.

>>> import numpy as np
>>> a = np.random.randn(3,2)
>>> b = a
>>> a is b
True
>>> a, b
(array([[-0.14563848,  2.11951025],
       [ 0.50913228, -0.61049821],
       [ 2.29055958, -0.83795141]]), array([[-0.14563848,  2.11951025],
       [ 0.50913228, -0.61049821],
       [ 2.29055958, -0.83795141]]))
>>> a -= 1
>>> a
array([[-1.14563848,  1.11951025],
       [-0.49086772, -1.61049821],
       [ 1.29055958, -1.83795141]])
>>> b
array([[-1.14563848,  1.11951025],
       [-0.49086772, -1.61049821],
       [ 1.29055958, -1.83795141]])
>>> a is b
True
>>> a = a - 1
>>> a
array([[-2.14563848,  0.11951025],
       [-1.49086772, -2.61049821],
       [ 0.29055958, -2.83795141]])
>>> b
array([[-1.14563848,  1.11951025],
       [-0.49086772, -1.61049821],
       [ 1.29055958, -1.83795141]])
>>> a is b
False
swag2198
  • 2,546
  • 1
  • 7
  • 18
  • So the operation `-=` is similar to the `append`, works as inplace, but why? Do you have more examples related to inplace operation? – storen Nov 20 '20 at 05:58
  • Take a look here: https://stackoverflow.com/questions/4370745/view-onto-a-numpy-array – swag2198 Nov 20 '20 at 05:59