import numpy as np
W = np.array([0,1,2])
W1 = W
W1 += np.array([2,3,4])
print W
W = np.array([0,1,2])
W1 = W
W1 = W1 + np.array([2,3,4])
print W
In Python, the operator +
(addition) redirects to either the __add__
method of the left operand or the __radd__
method of the right operand. We can ignore the latter case, since it is pretty rarely used (when addition does not commute).
The +=
operator redirects to the __iadd__
method, if one is defined. If __iadd__
is not defined on the left operand, a += b
becomes equivalent to a = a + b
.
The thing to remember with a += b
is that it is not just a.__iadd__(b)
(or type(a).__iadd__(a, b)
), it is a = type(a).__iadd__(a, b)
. On the one hand, this forced assignment allows immutable types like int
to define a meaningful +=
operation. On the other hand, the following fails with a TypeError
even though list addition happens in place:
tup = (['a'], ['b'])
tup[0] += ['c']
Numpy arrays are mutable objects that have clearly defined in place operations. If a
and b
are arrays of the same shape, a += b
adds the two arrays together, using a
as an output buffer. The function form of the operation is a = np.ndarray.__iadd__(a, b)
, which modifies a
and returns a
.
Similarly, a = a + b
is equivalent to a = np.ndarray.__add__(a, b)
. Unlike __iadd__
, however, __add__
creates and returns a completely new array to hold the result, which is then assigned to a
.
This has some additional implications for things like output type. If a
has dtype=int32
and b
has dtype=float64
, the in place operation will not change the type of a
. Instead b
's values will be truncated. The result of a + b
will have the wider type though, which would be float64
in this example.
All the basic Python operators have equivalent function implementations in numpy. a = a + b
is equivalent to a = np.add(a, b)
. a += b
is equivalent to a = np.add(a, b, out=a)
.