Python x = x + 1和x + = 1之间的差异

时间:2012-10-15 23:17:30

标签: python

在Python中,写x = x+1x += 1之间是否存在差异(语义,效率等)?

4 个答案:

答案 0 :(得分:14)

是。根据{{​​1}}类的编码方式,短格式可以选择就地修改x,而不是创建表示总和的新对象并将其重新绑定到相同的名称。如果你有多个变量引用同一个对象,这就有了意义 - 例如,使用list:

x

这是因为在幕后操作员调用了不同的魔术方法:>>> a = b = [] >>> a += [5] >>> a [5] >>> b [5] >>> a = a + [5] >>> a [5, 5] >>> b [5] 调用+__add__(预期不会修改他们的任何一个参数)和{{1尝试__radd__(如果感觉像是+=则允许修改__iadd__,如果self不存在,则回退到+逻辑。

答案 1 :(得分:5)

对于整数和浮点数,它们几乎相同,但lists

lis = lis+['foo']通过连接lis['foo']创建新列表,然后将结果分配给lis

和:

lis += [foo]相当于lis.extend([foo])

>>> lis = [1,2,3]
>>> id(lis)
3078880140L
>>> lis += ['foo']   #or lis.extend(['foo'])
>>> id(lis)          #same object
3078880140L


>>> lis = [1,2,3]
>>> id(lis)
3078880076L
>>> lis = lis+['foo']
>>> id(lis)            #new object
3078880012L

答案 2 :(得分:4)

是的,它们是编译为不同字节码的不同运算符:

>>> import dis
>>> def test1(x):
...    x = x + 1
... 
>>> def test2(x):
...    x += 1
... 
>>> dis.dis(test1)
  2           0 LOAD_FAST                0 (x) 
              3 LOAD_CONST               1 (1) 
              6 BINARY_ADD           
              7 STORE_FAST               0 (x) 
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         
>>> dis.dis(test2)
  2           0 LOAD_FAST                0 (x) 
              3 LOAD_CONST               1 (1) 
              6 INPLACE_ADD          
              7 STORE_FAST               0 (x) 
             10 LOAD_CONST               0 (None) 
             13 RETURN_VALUE         

在这种情况下,它不会产生巨大的差异,因为int是不可变的。从理论上讲,它们可以以不同的方式实现(取决于解释器),但这不会改变它对值的操作方式。

一般情况下,它们可以实现完全不同的东西(+由魔术方法__add__()+=__iadd()__实现) - 在大多数可变容器中例如,如果你有不同的名称引用同一个对象,它会产生很大的不同:

>>> x = []
>>> y = x
>>> x += [1]
>>> y
[1]
>>> x = x + [1]
>>> y
[1]
>>> x
[1, 1]

您可以看到,当我们将x分配给y时,它们都指向同一个列表。当我们使用+=时,我们会扩展列表并进行更改。当我们为x分配新值时,y仍然指向原始值并保持不变。

答案 3 :(得分:2)

它们不同,因为++=有单独的运算符。对于x = x + 1,解释器会将其视为x = x.__add__(1),而x += 1将为x = x.__iadd(1),这可能会更有效率,因为它不一定需要制作x

的副本