You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:58:53