小编典典

“ for”循环中i = i + 1和i + = 1有什么区别?

python

我今天发现了一件奇怪的事情,想知道是否有人可以阐明其中的区别?

import numpy as np

A = np.arange(12).reshape(4,3)
for a in A:
    a = a + 1

B = np.arange(12).reshape(4,3)
for b in B:
    b += 1

运行完每个for循环后,A没有改变,但是B在每个元素中添加了一个。我实际上使用该B版本在for循环内写入初始化的NumPy数组。


阅读 189

收藏
2020-12-20

共1个答案

小编典典

不同之处在于,一个修改数据结构本身(就地操作),b += 1而另一个仅 重新分配 变量a = a + 1


仅出于完整性考虑:

x += y不是总是 做就地操作,有(至少)三种例外情况:

  • 如果x 没有实现__iadd__则方法的x += y声明仅仅是一个速记x = x + y。如果x是类似的情况就是这种情况int

  • 如果__iadd__返回NotImplemented,Python将退回到x = x + y

  • __iadd__理论上讲,该方法可以实现为无法正常运行。但是,这样做真的很奇怪。

发生时,您的bs是numpy.ndarray实现__iadd__并返回自身的,因此您的第二个循环就地修改了原始数组。

您可以在Python文档“模拟数字类型”中了解更多信息

这些[
__i*__]方法称为实现增强算术分配(+=-=*=@=/=//=%=**=<<=>>=&=^=|=)。这些方法应尝试就地执行操作(修改self)并返回结果(可以是,但不一定是self)。如果未定义特定方法,则扩展分配将退回到常规方法。例如,如果x是具有__iadd__()方法的类的实例,x += y则等效于x = x.__iadd__(y)。否则,将x.__add__(y)与和y.__radd__(x)一起评估x + y。在某些情况下,扩充分配可能会导致意外错误(请参见为什么a_tuple[i] += ["item"]加法有效时会引发异常?),但实际上,该行为是数据模型的一部分。

2020-12-20