Python中关于+=和=+的问题
今天在LintCode刷题的时候,看别人的题解发现了一个很费解(对于我来说)的东西;
题目:
题解:
其中的
for i in nums:
self.sum += self.sum[-1] + i,
让我疑惑许久,于是开始各种寻找答案。
1、首先在编译器中debug,明白了 self.sum[-1] + i,
加逗号是为了让此表达式变成元组,将得到的结果添加到定义的self.num
列表去;
2、继续在编译器中尝试,但是怎么都不行,因为在列表中使用 + 进行拼接,只支持列表间的组合,而sums[-1]
和``` i ``都是int类型的;
>>> a = [6]
>>> a + (3,)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
3、继续尝试尝试尝试,终于发现
>>> a = a + (3,)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>> a += (3,)
>>> a
[1, 3]
为什么 + 和 += 不一样?经过搜索发现了一篇文章,解答了这个问题:https://justjavac.com/python/2013/03/11/if-x-is-list-why-does-x-ha-work-while-x-x-ha-throw-an-exception.html
总结:当在list中使用+
时,两个操作对象都必须是列表,而使用+=
时,相当于调用extend
,extend() 函数用于在列表末尾一次性追加另一个序列中的多个值,其参数只需要是可迭代序列即可。
补充:
在python中,+=和=+还涉及到可变对象/不可变对象,记录一下。
所涉及知识如下:
1、可变对象:字典dict、列表list、集合set;不可变对象:字符串、数值(int、float)、元组tuple;
2、一般情况下,可变对象有__iadd__
方法,不可变对象没有__iadd__
方法,只有__add__
方法(str是有__iadd__
方法的,但仍会改变内存地址);
3、__iadd__
方法直接在原地修改对象的值,不改变内存地址;而__add__
方法返回一个新的对象,因此内存地址会改变;
4、如果一个类没有实现__iadd__
方法,python会退而求其次调用__add__
方法;
5、+=调用的魔法方法是__iadd__
,而+(=+)调用的是__add__
;
因此,对于可变对象,=+操作调用__add__
,会修改内存地址;+=操作调用__iadd__
,不改变内存地址;对于不可变对象,没有__iadd__
方法,=+和+=操作,都调用的__add__
方法,因此内存地址都会改变。
参考资料:
https://zhuanlan.zhihu.com/p/115242988
https://blog.csdn.net/wangjunjie0817/article/details/85040077