Python中列表与字典使用+和+=的异常现象及原理求助
为什么列表与字典的
+和+=操作表现截然不同? 这确实是个容易让人摸不着头脑的Python细节!让我一步步拆解背后的原因:
1. 两种操作调用的是完全不同的方法
[1] + {2:3}触发的是列表的__add__方法。这个方法的设计目标是合并两个同类型的序列(比如列表+列表),它会创建一个新列表,并且要求右侧操作数必须是列表(或列表的子类)。当你传入字典时,类型不匹配,自然就抛出TypeError了,这和你预期的一致。a += {2:3}触发的是列表的__iadd__方法。这个方法的底层逻辑其实和list.extend()完全相同——它的设计是接受任何可迭代对象,而不仅仅是列表。它会遍历传入的可迭代对象,把每个元素逐个添加到原列表中(是原地修改,不会创建新列表)。
2. 字典作为可迭代对象时的默认行为
当你把字典当作可迭代对象使用时,Python默认会遍历它的键(就像执行for key in {2:3}会得到2一样)。所以a += {2:3}等价于:
a = [1] a.extend({2:3}) # 遍历字典的键,将2添加到列表 print(a) # 输出: [1, 2]
这就是为什么最终列表里多了2而没有报错的核心原因。
3. 关于CPython源码的补充
如果你想深挖底层实现,可以去看CPython的listobject.c文件:
__add__对应的是list_concat函数,它会先检查右侧对象是否为列表类型(或其子类),不满足就直接抛出错误。__iadd__最终会调用list_extend函数,这个函数会先获取传入对象的迭代器(通过PyIter_GetIter),然后逐个迭代元素并添加到列表中,只要传入对象是可迭代的就可以,不限制类型。
内容的提问来源于stack exchange,提问作者arjoonn
相关产品推荐
相关产品推荐

