+= in Python 将其分配给第三个变量时
+= in Python when assigning it to third variable
当我查看 Python 中 += 运算符的含义时,我查看了类似问题的答案:What exactly does += do in python?。但在下面的代码摘录中:
increments += arr[i-1] - arr[i]
使用了第三个变量。如果我理解这个概念,它会从 arr[i-1]
中减去 arr[i]
并将其添加到 increments
的值,并将结果分配给 increments
。细说一下:上面的语句是不是类似于
increments = increments + (arr[i-1] - arr[i])
还有更多吗?
An augmented assignment evaluates the target (which, unlike normal assignment statements, cannot be an unpacking) and the expression list, performs the binary operation specific to the type of assignment on the two operands, and assigns the result to the original target. The target is only evaluated once.
An augmented assignment expression like x += 1
can be rewritten as x = x + 1
to achieve a similar, but not exactly equal effect. In the augmented version, x
is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.
Unlike normal assignments, augmented assignments evaluate the left-hand side before evaluating the right-hand side. For example, a[i] += f(x)
first looks-up a[i]
, then it evaluates f(x)
and performs the addition, and lastly, it writes the result back to a[i]
.
With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible in-place behavior, the binary operation performed by augmented assignment is the same as the normal binary operations.
For targets which are attribute references, the same caveat about class and instance attributes applies as for regular assignments.
(我在第二段强调)
所以是的,它不仅仅是 increments = increments + (arr[i-1] - arr[i])
。它的重要程度取决于您将运算符应用于什么。
To elaborate: is the above statement similar to
increments = increments + (arr[i-1] - arr[i])
这取决于 "increments" 的类型。
关于核心内置类型(以及其他试图遵循它们设置的模式的类型),+ 和 += 之间至少有两个显着差异。
- 类型可变的地方 += 就地执行修改,同时 + 创建新对象。
- 对于列表,+= 比 + 更灵活,+ 将只接受另一个列表,但 += 将接受任何可迭代对象。
数字是不可变的,因此对于数字,这两个语句的行为相同。然而,有趣的是,看看我们是否能找出一些它们确实表现不同的情况。
我们可以使用的类型非常有限,因为相对较少的类型同时支持“+”和“-”,而且大多数类型只支持相同类型的操作。将 increments 设为列表和将元素设为 arr sets 的组合是证明差异的一种方式。
increments=[]
i = 1
arr=[{"foo","bar"},{"bar","baz"}]
increments += arr[i-1] - arr[i]
print(increments)
"Prints ['foo']"
increments=[]
i = 1
arr=[{"foo","bar"},{"bar","baz"}]
increments = increments + (arr[i-1] - arr[i])
print(increments)
引发异常 "TypeError: can only concatenate list (not "set") to list
但这是一个相当人为的例子,为了更现实的东西,我们想要一个可变的类型并支持“+”和“-”。我认为核心内置类型中没有任何此类类型,但一种广泛使用的类型是 numpy 中的 "array" 类型。
from numpy import array
increments=array((1,2))
oldincrements=increments
i = 1
arr=[array((3,4)),array((5,6))]
increments += arr[i-1] - arr[i]
print(repr(oldincrements)+' '+repr(increments))
打印 "array([-1, 0]) array([-1, 0])"。 numpy 数组已就地修改,因此 "oldincrements" 和 "increments" 都受到影响。
from numpy import array
increments=array((1,2))
oldincrements=increments
i = 1
arr=[array((3,4)),array((5,6))]
increments = increments + (arr[i-1] - arr[i])
print(repr(oldincrements)+' '+repr(increments))
打印 "array([1, 2]) array([-1, 0])" 增量指向的数组未就地修改,而是创建了一个新数组并将其分配给 "increments"。所以"oldincrements"没有受到影响。
当我查看 Python 中 += 运算符的含义时,我查看了类似问题的答案:What exactly does += do in python?。但在下面的代码摘录中:
increments += arr[i-1] - arr[i]
使用了第三个变量。如果我理解这个概念,它会从 arr[i-1]
中减去 arr[i]
并将其添加到 increments
的值,并将结果分配给 increments
。细说一下:上面的语句是不是类似于
increments = increments + (arr[i-1] - arr[i])
还有更多吗?
An augmented assignment evaluates the target (which, unlike normal assignment statements, cannot be an unpacking) and the expression list, performs the binary operation specific to the type of assignment on the two operands, and assigns the result to the original target. The target is only evaluated once.
An augmented assignment expression like
x += 1
can be rewritten asx = x + 1
to achieve a similar, but not exactly equal effect. In the augmented version,x
is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.Unlike normal assignments, augmented assignments evaluate the left-hand side before evaluating the right-hand side. For example,
a[i] += f(x)
first looks-upa[i]
, then it evaluatesf(x)
and performs the addition, and lastly, it writes the result back toa[i]
.With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible in-place behavior, the binary operation performed by augmented assignment is the same as the normal binary operations.
For targets which are attribute references, the same caveat about class and instance attributes applies as for regular assignments.
(我在第二段强调)
所以是的,它不仅仅是 increments = increments + (arr[i-1] - arr[i])
。它的重要程度取决于您将运算符应用于什么。
To elaborate: is the above statement similar to
increments = increments + (arr[i-1] - arr[i])
这取决于 "increments" 的类型。
关于核心内置类型(以及其他试图遵循它们设置的模式的类型),+ 和 += 之间至少有两个显着差异。
- 类型可变的地方 += 就地执行修改,同时 + 创建新对象。
- 对于列表,+= 比 + 更灵活,+ 将只接受另一个列表,但 += 将接受任何可迭代对象。
数字是不可变的,因此对于数字,这两个语句的行为相同。然而,有趣的是,看看我们是否能找出一些它们确实表现不同的情况。
我们可以使用的类型非常有限,因为相对较少的类型同时支持“+”和“-”,而且大多数类型只支持相同类型的操作。将 increments 设为列表和将元素设为 arr sets 的组合是证明差异的一种方式。
increments=[]
i = 1
arr=[{"foo","bar"},{"bar","baz"}]
increments += arr[i-1] - arr[i]
print(increments)
"Prints ['foo']"
increments=[]
i = 1
arr=[{"foo","bar"},{"bar","baz"}]
increments = increments + (arr[i-1] - arr[i])
print(increments)
引发异常 "TypeError: can only concatenate list (not "set") to list
但这是一个相当人为的例子,为了更现实的东西,我们想要一个可变的类型并支持“+”和“-”。我认为核心内置类型中没有任何此类类型,但一种广泛使用的类型是 numpy 中的 "array" 类型。
from numpy import array
increments=array((1,2))
oldincrements=increments
i = 1
arr=[array((3,4)),array((5,6))]
increments += arr[i-1] - arr[i]
print(repr(oldincrements)+' '+repr(increments))
打印 "array([-1, 0]) array([-1, 0])"。 numpy 数组已就地修改,因此 "oldincrements" 和 "increments" 都受到影响。
from numpy import array
increments=array((1,2))
oldincrements=increments
i = 1
arr=[array((3,4)),array((5,6))]
increments = increments + (arr[i-1] - arr[i])
print(repr(oldincrements)+' '+repr(increments))
打印 "array([1, 2]) array([-1, 0])" 增量指向的数组未就地修改,而是创建了一个新数组并将其分配给 "increments"。所以"oldincrements"没有受到影响。