把多个列表合成一个,最稳妥的做法是用 extend 把元素逐个加进原列表;如果你想要的是一条全新列表、不想改动原来的对象,就用加号拼接。本文先说清 Python 列表合并的两种思路,再给出可复现的写法、对比和验证。

你正在做练习,手上有 a、b、c 三个列表,想把它们合成一个 result。这时候最自然的念头是「把后面的列表接上来」,但「接」有两种完全不同的含义:一种是生成一个全新的汇总列表,原列表纹丝不动;另一种是往某个原列表里追加元素,原列表会被改变。选错方式,后面排查半天都找不到原因。今天这篇文章,编程狮就把 Python 多个列表合并讲透。
一、先分清「拼接」和「展开」两件事
很多人卡住,是因为把两个概念混在了一起。所谓拼接,是指用 + 运算符得到一条新列表,老的 a、b 都不受影响。所谓展开,是指用 extend 或星号 * 把多个列表里的元素平铺进同一个容器,原容器会被改写。
举个容易踩的反例:如果你写 new = []; new.append(a); new.append(b),得到的其实是 [[1, 2, 3], [4, 5]]——两层列表。这算不上「合并」,只是把两个列表装进了另一个列表。真正的合并要去掉那层外壳,让元素直接平铺出来,而不是套娃。
⚠️ 注意:extend 会修改调用它的那个列表本身。如果你后面还要用原来的
a,却在前面悄悄 extend 过,它已经不是当初的样子了。
如果你还没系统学过语法,可以先过一遍 Python3 基础教程,把列表这一章的增删改查先过一遍,后面看代码会更顺。
二、方案一:用加号拼接,最直观也最安全
加号拼接的好处是「不污染原数据」。它返回一个新列表,你愿意存到哪个变量都行。
a = [1, 2, 3]
b = [4, 5]
c = [6, 7]
result = a + b + c
print(result)
上面这段做了什么:先把 a 和 b 拼成临时列表,再和 c 拼,最后赋给 result。执行后你应该看到 [1, 2, 3, 4, 5, 6, 7]。此时 a、b、c 三个原列表一个都没变。
如果记不住语法细节,Python 速查手册 可以放在旁边随时翻。它的缺点是:每用一次 +,都会生成一份中间列表,列表特别长、数量特别多时,内存会多占一些。

三、方案二:用 extend 原地展开,省内存
当你确定「就要改 a 本身」,extend 是最直接的写法。它把参数里的每一个元素追加进调用者,而不是把参数整个当成一个元素塞进去。
a = [1, 2, 3]
b = [4, 5]
a.extend(b)
print(a)
执行后 a 变成 [1, 2, 3, 4, 5]。注意这里没有新列表产生,a 被就地改写了。想立刻试效果,可以打开 Python 在线运行 把上面的代码粘进去跑一遍。
如果一次要并入多个列表,可以连续调用 extend:a.extend(b); a.extend(c),效果和 a + b + c 的展开一致,但全程只改写 a 一个对象,不会产生中间列表。它和 + 的关键差别就在「是否新建对象」:你后续还要引用原 a 就别用 extend。
一个高频错误是把 a.append(b) 当成合并——append 会把 b 整个当成「一个元素」塞进去,结果是 [1, 2, 3, [4, 5]],多出来一层嵌套。合并要的是平铺,不是套娃。
四、方案三:用 itertools.chain 与星号展开做只读汇总
如果原列表一个都不想改,又想避免多次 + 产生的中间列表,可以用 itertools.chain。它返回的是一个迭代器,按需吐出元素,非常适合「只读汇总后再处理」的场景。
from itertools import chain
a = [1, 2]
b = [3, 4]
c = [5, 6]
result = list(chain(a, b, c))
print(result)
| 方式 | 是否改原列表 | 是否产生中间列表 | 适合场景 |
|---|---|---|---|
a + b + c |
否 | 是 | 列表少、要清晰直观 |
a.extend(b) |
是 | 否 | 确定要改 a 本身 |
list(chain(...)) |
否 | 否 | 多列表只读汇总、按需处理 |
[*a, *b, *c] |
否 | 是 | 写法最短、数量不多时 |
星号解包的写法 [*a, *b, *c] 在 Python 3.5 之后就能用,读起来很清爽,本质仍是拼接,会生成新列表。
如果你的输入不是三个独立列表,而是一个「列表的列表」,比如 groups = [[1, 2], [3, 4], [5, 6]],想压成一维,用 chain.from_iterable(groups) 比手动拼接更省事:它跳过外层容器逐层展开,同样不改原数据、返回迭代器,记得用 list() 包一层再取值。对应的列表推导式写法是 [x for sub in groups for x in sub],逻辑更直白,适合还需要顺便做转换的场景。
五、踩坑清单
把三个最容易翻车的地方列出来,每个都给现象、原因和办法。
- 现象:
append之后列表里多出一层方括号。原因:append 把整个列表当一个元素。解决:改extend或chain。 - 现象:拼接后原列表被改了,后续逻辑全乱。原因:用了
extend却以为是新列表。解决:要保原数据就用+或chain。 - 现象:大量列表拼接时程序变慢、内存涨。原因:链式
+反复生成中间列表。解决:改用chain,或者先建空列表再循环extend。 - 现象:合并「列表的列表」后结果还是两层方括号。原因:直接对子列表用
+,只是把子列表当元素拼接。解决:用chain.from_iterable或双层列表推导式把外层压平。
验证结果最直接:随便挑一个合并后的列表,用 len(result) 看长度是否等于各列表长度之和,再用 result == [1,2,3,4,5,6] 这种整列表比对确认顺序没错。预期结果(未在本机执行)是按元素顺序首尾相接,且不包含嵌套子列表。
合并前先 检查 各个列表是不是同一个对象引用,避免改一个动全部;如果来自配置 项,先解析再合并。注意 边界:嵌套层级很深时,单纯用 + 并不会帮你摊平,那就得上 from_iterable。整体写法更 适用 于把多段结果拼成一份完整列表。
总结
Python 多个列表合并,核心是分清楚「拼接」和「展开」:要新列表用 + 或 [*a, *b],要就地改写用 extend,要多列表只读汇总用 itertools.chain。三者没有绝对优劣,只看你当下要不要保留原数据、在不在意中间开销。
要点带走:
- 加号拼接不污染原列表,但会产生中间列表;
- extend 原地展开最省内存,但会改写调用者;
- chain 适合只读汇总,按需吐元素、不占额外内存。
下一步如果你常和列表打交道,可以进一步看看过滤和去重怎么配合,让汇总后的数据更干净。
延伸学习
想把这块知识系统补齐,可以按这个顺序来:
- 先过一遍 Python 系统学习路径,把列表、元组、字典的增删改查铺平;
- 遇到汇总后的脏数据,翻 Python 列表怎么去重 看几种去重写法;
- 想跟着课程边学边练,Python 配套课程 是图文微课形式,适合巩固。
常见问题
Q:合并很多个列表,用加号还是 chain 更好?
A:如果你只是要一条最终列表、数量在十几个以内,加号最直观。如果列表非常多、或者你只想逐个处理元素而不必真的拼成完整列表,用 chain 更省内存。
Q:为什么我用了 extend 之后原列表变了?
A:extend 的设计就是「就地展开」,它会修改调用它的那个列表。想要原列表不变,就改成 new = a + b 这种拼接写法。
Q:append 和 extend 到底差在哪?
A:append 把参数整个当一个元素塞进去,extend 把参数里的每个元素逐个铺进去。合并要平铺就选 extend,想保留子列表结构才用 append。

TRAE-AI编程



