【问题标题】:+ and += operators are different? [duplicate]+ 和 += 运算符不同? [复制]
【发布时间】:2011-01-02 21:25:56
【问题描述】:
>>> c = [1, 2, 3]
>>> print(c, id(c))
[1, 2, 3] 43955984
>>> c += c
>>> print(c, id(c))
[1, 2, 3, 1, 2, 3] 43955984
>>> del c
>>> c = [1, 2, 3]
>>> print(c, id(c))
[1, 2, 3] 44023976
>>> c = c + c
>>> print(c, id(c))
[1, 2, 3, 1, 2, 3] 26564048

有什么区别? += 和 + 不应该只是语法糖吗?

【问题讨论】:

  • 您的示例清楚地表明它们不是。 += 显然是添加到该对象中,并且 x = a + b(即使 a = b = x)显然会创建一个新结果并将其分配给 LHS。我认为检查每个添加以查看它是否是简单添加(如上所述)并将其优化为 += 会适得其反。
  • 为什么投反对票?我承认标题可能会更好,但问题本身非常有效
  • 这个问题有一些关于列表连接操作的很好的附加信息stackoverflow.com/questions/2022031/…

标签: python list operators


【解决方案1】:

docs explain it very well,我想:

__iadd__()
调用这些方法来实现增强的算术分配 (+=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=)。 这些方法应该尝试就地执行操作(修改self)并返回结果(可以是但不一定是self)。如果特定方法是未定义,扩充的分配回退到正常的方法。例如,要执行语句x += y,其中x 是具有__iadd__() 方法的类的实例,调用x.__iadd__(y)

+= 旨在实现就地修改。在简单添加的情况下,将创建新对象并使用已使用的名称 (c) 对其进行标记。

此外,您会注意到 += 运算符的这种行为仅可能因为列表的可变性质。整数 - 不可变类型 - 不会产生相同的结果:

>>> c = 3
>>> print(c, id(c))
3 505389080
>>> c += c
>>> print(c, id(c))
6 505389128

【讨论】:

  • 另一点是评估/优先级的顺序。在c= c + c 中,c + c 在分配c= 之前被评估,而在c+=c 中,本身没有两个不同的操作。
【解决方案2】:

他们不一样

c += c 将 c 内容的副本附加到 c 本身

c = c + c 用 c + c 创建新对象

【讨论】:

    【解决方案3】:

    对于

    foo = []
    

    foo+=foofoo.extend(foo) 的语法糖(而不是 foo = foo + foo

    在第一种情况下,您只是将列表的成员附加到另一个列表中(而不是创建新列表)。

    id 在第二种情况下发生了变化,因为通过添加两个列表创建了一个新列表。偶然的是,两者都是相同的,并且结果被绑定到相同的标识符而不是曾经指向它们的标识符。

    如果你用不同的列表(而不是 c 本身)重新表述这个问题,它可能会变得更清楚。

    【讨论】:

      【解决方案4】:

      += 运算符将第二个列表附加到第一个列表,但修改是就地的,因此 ID 保持不变。

      当您使用 + 时,会创建一个新列表,最后的“c”是一个新列表,因此它具有不同的 ID。

      虽然这两种操作的最终结果是相同的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-09
        • 2020-01-25
        • 1970-01-01
        • 2011-03-06
        • 2013-09-24
        • 1970-01-01
        • 2019-12-27
        相关资源
        最近更新 更多