
在Python中,list.insert() 和 list.append() 虽然都用于向列表添加元素,但底层机制和性能差异显著——append() 是均摊 O(1) 的高效操作,而 insert() 在非末尾位置插入时是 O(n) 时间复杂度,且会引发大量元素位移。
append():末尾追加,几乎无开销
append() 总是在列表末尾添加元素。CPython 实现中,列表对象内部维护一个动态数组,预留了额外容量(over-allocation)。只要未超出当前容量,追加就是纯指针赋值+长度递增,无需移动已有元素。
- 平均时间复杂度:O(1)(均摊)
- 空间预分配策略使连续 append 多数情况下不触发 realloc
- 适合构建新列表、收集循环结果等场景
insert():任意位置插入,代价随索引增大而升高
insert(i, x) 将元素插入到索引 i 处(原 i 及之后所有元素后移一位)。这意味着 Python 必须从末尾开始,将索引 i 到 len-1 的所有元素逐个向后复制一位。
- 时间复杂度:O(n − i),最坏情况是
insert(0, x),需移动全部 n 个元素 - 即使插入位置靠近末尾(如
insert(-1, x)),仍需移动至少一个元素,无法享受 append 的优化 - 频繁在开头或中间插入,会导致性能急剧下降,尤其对大列表
实际性能差距有多大?
以万级列表为例:
立即学习“Python免费学习笔记(深入)”;
- 对长度为 10000 的列表执行 1000 次
append():通常耗时 - 同样规模下执行 1000 次
insert(0, x):可能耗时 >100ms(慢百倍以上) - 用
insert(len(lst), x)模拟 append?仍比原生 append 慢约 2–3 倍(因额外索引计算与边界检查)
什么情况下该用 insert?如何规避性能陷阱?
除非业务逻辑明确要求“保持插入顺序”或“按序构建”,否则应优先避免在中间/开头用 insert。
- 需要有序插入?考虑
bisect.insort()(基于二分查找 + insert,仍慢但逻辑正确)或改用sorted list类库(如sortedcontainers) - 需头插?先用
append(),最后调用list.reverse();或用collections.deque(头尾插入均为 O(1)) - 批量插入多个元素?先收集到临时列表,再用
lst[i:i] = temp_list(切片赋值,C 层优化,比多次 insert 快得多)










