Python 中如何展平(flatten)嵌套列表?
展平二维列表最简洁的写法是列表推导式 [x for sub in l for x in sub]。本文介绍推导式、itertools.chain、sum 技巧及多层嵌套的递归方案。
二维列表(列表的列表)展平的标准写法:[item for sublist in l for item in sublist]。更Pythonic的替代:list(itertools.chain.from_iterable(l))。多层任意深度嵌套则需要递归。
方法一:列表推导式(二维)
l = [[1, 2], [3, 4], [5, 6]]
flat = [item for sublist in l for item in sublist]
print(flat) # [1, 2, 3, 4, 5, 6]
可读性更好的等价循环:
flat = []
for sublist in l:
for item in sublist:
flat.append(item)
方法二:itertools.chain.from_iterable
from itertools import chain
flat = list(chain.from_iterable(l))
惰性求值,大列表更省内存,是很多场景下的最优解。
方法三:任意深度嵌套(递归)
def flatten(x):
result = []
for item in x:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
print(flatten([1, [2, [3, [4]]]])) # [1, 2, 3, 4]
避坑:sum 技巧
sum(l, []) # 能展平二维列表,但时间复杂度 O(n²),大列表极慢,不推荐
常见问题(FAQ)
Q:numpy 数组怎么展平?
A:用 arr.flatten()(返回副本)或 arr.ravel()(尽量返回视图,更快)。
Q:只展平一层 vs 全部展平?
A:前两种方法只展平一层(二维→一维);任意深度必须用递归或 more_itertools.collapse 这类工具。
Q:列表里混着字符串会被拆开吗?
A:字符串也是可迭代对象,chain.from_iterable 会把字符串拆成单字符——数据里混有字符串时需要在递归方案里特判 isinstance(item, (str, bytes)) 不展开。