append() 原地添加单个元素,时间复杂度 O(1);+= 等价于 extend(),要求右侧可迭代,会迭代展开添加。二者均只复制引用、不深拷贝,但语义和错误模式不同。
list.append() 直接在列表末尾插入一个对象引用,时间复杂度 O(1)(均摊),且不涉及任何拷贝或迭代。它只修改 list 的内部指针数组,扩容时才发生一次内存重分配。
常见误用是把它当批量操作:比如 lst.append([1, 2, 3]) 会把整个列表作为一个元素嵌套进去,而不是展开。这点和 += 完全不同。
实操建议:
append() —— 语义清晰、开销最小append() 替代 extend() 或 += 来“假装”批量添加extend() 或 += [x, y, z],而非循环调用 append()
+= 对列表不是简单赋值叠加,而是触发 list.__iadd__() 方法,该方法内部行为与 extend() 完全一致:它迭代右侧对象(必须是可迭代的),逐个调用 append()。所以 lst += [x] 和 lst.extend([x]) 行为相同,但比 lst.append([x]) 多一层迭代和类型检查。
关键细节:
lst += [x] 要求右侧是可迭代对象;[x] 是合法的,但 lst += x(x 是 int)会报 TypeError: 'int' object is not iterable
__iter__)extend() 一样,若右侧很大,+= 会预估容量并一次性扩容,比循环 append() 更高效对单个元素,append() 比 += [x] 快约 1.2–1

lst += x(x 是 int)→ 立即报错,提示明确lst.append([x]) → 不报错,但产生意外嵌套结构,后期引发 TypeError 或逻辑 bug,更难定位+= 支持任意可迭代对象:lst += "ab" 会拆成 ['a', 'b'];append() 则把字符串当一个整体所以选哪个,主要看你要“加一个东西”还是“加一批东西的展开结果”。
无论是 append() 还是 += [x],都只是把对象的引用追加到列表的指针数组中,不会对 x 本身做深拷贝或浅拷贝。如果你改了 x 的内容(比如它是 list 或 dict),所有持有该引用的地方都会看到变化。
容易被忽略的一点:
+= 在扩容时可能触发一次底层内存 realloc,而 append() 在同样扩容时机也做同样的事 —— 所以二者在内存分配行为上没有本质区别
+= 若右侧是生成器(如 lst += (x for x in range(1000))),会强制完全消费并缓存全部元素,可能导致临时内存上升;append() 没这问题,因为它根本不接受生成器作为参数