1. in-place 运算

1.1. += 运算

+= 是一个 in-place 运算符,看如下例子:

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

结果如下:

>>> print a
[1,2]
>>> print b
[1,2]

如果改变成如下形式:

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

则结果如下:

>>> print a
[1,2]
>>> print b
[]

Note

a = a + [1,2] 不是 in-place 运算,尽管使用了同一个变量名。

1.2. add 和 iadd

operator 包中有两个操作:addiaddadd 是正常加运算, iadd 是原位加运算。

_add_

does simple addition, takes two arguments, returns the sum and stores it in other variable without modifying any of the argument. Normal operator’s add() method, implements “a+b” and stores the result in the mentioned variable.

_iadd_

also takes two arguments, but it makes in-place change in 1st argument passed by storing the sum in it. As object mutation is needed in this process, immutable targets such as numbers, strings and tuples, shouldn’t have _iadd_ method. Inplace operator’s iadd() method, implements “a+=b” if it exists (i.e in case of immutable targets, it doesn’t exist) and changes the value of passed argument. But if not, “a+b” is implemented.

1.2.1. 不可变目标

对于不可变目标(Immutable Targets),如数字、字符串、元组, _add__iadd_ 结果是一样的,输入实参不会发生改变。

1import operator
2
3x = 5
4y = 6
5a = 5
6b = 6
7
8z = operator.add(a, b)
9p = operator.iadd(x, y)

结果如下:

>>> print z
11
>>> print a
5
>>> print p
11
>>> print x
5

1.2.2. 可变目标

对于可变目标(Mutable Targets),如列表、字典、集合,输入实参会被重现赋值和更新。

1import operator
2
3a = [1,2,4,5]
4b = [1,2,4,5]
5
6z = operator.add(a, [1,2,3])
7p = operator.iadd(b, [1,2,3])

结果如下:

>>> print z
[1, 2, 4, 5, 1, 2, 3]
>>> print p
[1, 2, 4, 5, 1, 2, 3]
>>> print a
[1, 2, 4, 5]
>>> print b
[1, 2, 4, 5, 1, 2, 3]

Note

不可变目标 (数字、字符串、元组)作为函数参数,相当于 值传递 ,函数对实参进行拷贝。

可变目标 (列表、字典、集合)作为函数参数,相当于 引用传递 ,函数对实参的修改有效。这里的修改是通过调用变量的成员方法,如果在函数中通过 = 运算符直接对该变量重新赋值,那么这种改变也不会影响实参。

1.3. 参考资料

  1. pytorch issue:

  1. GeeksforGeeks: