You don't even need the function call to see this difference.
x
is an array:
In [138]: type(x)
Out[138]: numpy.ndarray
Indexing an element of the array returns a np.float64
object. It in effect "takes" the value out of the array; it is not a reference to the element of the array.
In [140]: y=x[0]
In [141]: type(y)
Out[141]: numpy.float64
This y
is a lot like a python float; you can +=
the same way:
In [142]: y += 1
In [143]: y
Out[143]: 1.0
but this does not change x
:
In [144]: x
Out[144]: array([0.])
But this does change x
:
In [145]: x[0] += 1
In [146]: x
Out[146]: array([1.])
y=x[0]
does a x.__getitem__
call. x[0]=3
does a x.__setitem__
call. +=
uses __iadd__
, but it's similar in effect.
Another example:
Changing x
:
In [149]: x[0] = 3
In [150]: x
Out[150]: array([3.])
but attempting to do the same to y
fails:
In [151]: y[()] = 3
Traceback (most recent call last):
File "<ipython-input-151-153d89268cbc>", line 1, in <module>
y[()] = 3
TypeError: 'numpy.float64' object does not support item assignment
but y[()]
is allowed.
basic
indexing of an array with a slice does produce a view
that can be modified:
In [154]: x = np.zeros(5)
In [155]: x
Out[155]: array([0., 0., 0., 0., 0.])
In [156]: y= x[0:2]
In [157]: type(y)
Out[157]: numpy.ndarray
In [158]: y += 1
In [159]: y
Out[159]: array([1., 1.])
In [160]: x
Out[160]: array([1., 1., 0., 0., 0.])
===
Python list and dict examples of the x[0]+=1
kind of action:
In [405]: alist = [1,2,3]
In [406]: alist[1]+=12
In [407]: alist
Out[407]: [1, 14, 3]
In [408]: adict = {'a':32}
In [409]: adict['a'] += 12
In [410]: adict
Out[410]: {'a': 44}
__iadd__
can be thought of a __getitem__
followed by a __setitem__
with the same index.