HOWTO · Python

如何在 Python 中串联两个或多个列表

本教程介绍如何在 Python 中拼接两个或多个列表,并说明如何根据是否需要修改原列表以及所需的结果类型选择合适的方法。

本页内容

如果需要创建新列表,可以使用 +;如果要向现有列表添加元素,可以使用 extend() 或 +=。拼接多个列表时,迭代解包语法简洁明了;如果要以迭代器的形式处理元素,itertools.chain() 很实用。下面的示例使用相同的列表,便于比较每种方法的结果。

Python 列表按顺序保存元素,可以通过多种方式组合。选择方法时,应考虑是否需要改变原列表,以及后续操作需要的是列表还是迭代器。

使用 + 运算符拼接列表

+ 运算符会创建一个新列表,并保持两个输入列表不变。它可以拼接两个或多个列表,每增加一个 +,就会再拼接一个列表。

first = [1, 2, 3]
second = [4, 5]
third = [6, 7]
combined = first + second + third
print(combined)

例如,赋值语句 first = first + second 会让 first 指向新建的组合列表;它不会原地扩展原列表对象。如果希望保留源列表以供后续使用,可以选择 +。

使用 extend() 扩展列表

extend() 会将可迭代对象中的每个元素添加到调用它的列表末尾。它会修改该列表,并返回 None,因此应将目标列表保存在变量中,而不要把该方法调用的结果赋给变量。

first = [1, 2, 3]
second = [4, 5]
first.extend(second)

这与 first.append(second) 不同:append() 会把 second 整体作为一个嵌套元素添加进去,而 extend() 会逐个添加其中的元素。可迭代对象可以是列表、元组或其他可迭代对象。

使用 += 原地扩展列表

对于列表,+= 会将右侧可迭代对象中的元素添加到现有列表中,效果与 extend() 类似。

first = [1, 2, 3]
second = [4, 5]
first += second

如果要更新左侧列表,+= 是一种简洁的选择。相比之下,first = first + second 会创建一个新列表,并将名称 first 绑定到它。

使用解包语法拼接列表

迭代解包会将每个源列表中的元素放入一个新的列表字面量中。它支持拼接两个或多个列表,并且不会修改输入列表。

first = [1, 2, 3]
second = [4, 5]
third = [6, 7]
combined = [*first, *second, *third]

* 会在方括号内展开每个可迭代对象,从而生成一个扁平列表。这种解包形式在 Python 3.5 中引入(参见 PEP 448)。

使用 itertools.chain()

itertools.chain() 会按顺序生成其输入可迭代对象中的元素。它返回一个迭代器;如果需要得到具体的列表,可以将其传给 list()。

from itertools import chain

first = [1, 2, 3]
second = [4, 5]
third = [6, 7]
combined = list(chain(first, second, third))

如果只需循环处理这些值,保留迭代器就能避免预先构建组合列表。请参阅 Python 文档中关于 itertools.chain() 的说明。

使用循环或列表推导式拼接列表

如果需要对每个元素进行额外处理,循环会很有用。append() 一次添加一个元素,因此需要遍历每个源列表,才能生成扁平结果。

lists = [[1, 2, 3], [4, 5], [6, 7]]
combined = []
for current in lists:
    for item in current:
        combined.append(item)

列表推导式可以简洁地表达相同的遍历过程:

lists = [[1, 2, 3], [4, 5], [6, 7]]
combined = [item for current in lists for item in current]

这两种方法都会创建一个新列表。如果循环中的步骤需要解释或额外逻辑,可以使用循环;如果只需直接展平元素,列表推导式会更简洁。

比较这些方法并选择合适的一种

方法 是否会修改输入? 结果 是否适用于多个列表?
+ 否 新列表 是
extend() 是,目标列表 调用时返回 None 对每个源列表调用一次
+= 是,左侧列表 原地修改左侧列表 对每个源列表分别应用
解包 否 新列表 是
itertools.chain() 否 迭代器 是
循环或列表推导式 否 新列表 是

如果要生成易读的新列表,可以使用 + 或解包语法;如果要扩展现有列表,可以使用 extend() 或 +=。如果后续操作适合使用迭代器,可以选择 itertools.chain();如果后续代码需要列表索引或列表方法,则用 list() 将其转换为列表。这些方法在内存分配和修改行为上有所不同,但输入大小和工作负载各异时,并不存在普遍适用的性能排名;如果运行时间或内存占用是决定因素,请使用有代表性的数据进行测量。

总结

拼接两个或多个 Python 列表时,可以用 + 或解包语法创建新列表,用 extend() 或 += 修改目标列表,也可以用 itertools.chain() 惰性地迭代元素。如果更适合周边代码的写法是循环或列表推导式,也可以用它们构建新的扁平列表。