Why does python/numpy's += mutate the original array?

前端 未结 4 1241
我寻月下人不归
我寻月下人不归 2020-12-02 01:40
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

4条回答
  •  一整个雨季
    2020-12-02 02:14

    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).

提交回复
热议问题