如何将嵌套列表转换为扁平列表

如何将嵌套列表转换为扁平列表

技术背景

在Python编程中,经常会遇到将嵌套列表转换为扁平列表的需求。例如,处理多维数据、解析复杂的数据结构等场景下,需要将嵌套的列表展开为一维列表,以便进行后续的数据处理和分析。

实现步骤

1. 使用嵌套列表推导式

嵌套列表推导式是一种简洁的方式来实现列表扁平化。

1
2
xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = [x for xs in xss for x in xs]

2. 使用传统的循环方式

使用两层循环遍历嵌套列表,将元素添加到新列表中。

1
2
3
4
5
xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flat_list = []
for xs in xss:
for x in xs:
flat_list.append(x)

3. 定义函数实现

将上述逻辑封装成函数,提高代码的复用性。

1
2
def flatten(xss):
return [x for xs in xss for x in xs]

4. 使用itertools.chain()itertools.chain.from_iterable()

itertools模块提供了高效的迭代工具,chain()chain.from_iterable()可以方便地将嵌套列表扁平化。

1
2
3
4
import itertools
list2d = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
merged = list(itertools.chain(*list2d)) # 使用 chain()
merged = list(itertools.chain.from_iterable(list2d)) # 使用 chain.from_iterable()

5. 使用functools.reduce()operator.concat

functools.reduce()可以对可迭代对象进行累积操作,结合operator.concat可以实现列表的拼接。

1
2
3
4
from functools import reduce
import operator
xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
out = reduce(operator.concat, xss)

6. 通用的扁平化方法

可以处理嵌套和混合容器中的对象,包括数字、字符串等。

1
2
3
4
5
6
7
8
9
from typing import Iterable

def flatten(items):
for x in items:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
for sub_x in flatten(x):
yield sub_x
else:
yield x

7. 使用第三方库

iteration_utilities库中的deepflatten函数,可以处理深度嵌套的列表。

1
2
3
from iteration_utilities import deepflatten
l = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
list(deepflatten(l))

核心代码

以下是几种常见方法的核心代码:

嵌套列表推导式

1
2
def flatten(xss):
return [x for xs in xss for x in xs]

itertools.chain.from_iterable()

1
2
3
import itertools
def flatten(xss):
return list(itertools.chain.from_iterable(xss))

通用扁平化函数

1
2
3
4
5
6
7
8
from typing import Iterable
def flatten(items):
for x in items:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
for sub_x in flatten(x):
yield sub_x
else:
yield x

最佳实践

  • 性能优先:如果追求性能,推荐使用itertools.chain.from_iterable()functools.reduce(operator.iconcat, a, []),它们在处理大量数据时效率较高。
  • 代码简洁:如果对代码简洁性要求较高,嵌套列表推导式是一个不错的选择。
  • 处理复杂嵌套:对于复杂的嵌套结构,通用的扁平化方法或第三方库的deepflatten函数更合适。

常见问题

1. 性能问题

使用sum(xss, [])或基于+操作的方法在处理大量子列表时性能较差,因为会多次分配新的中间结果列表对象,并复制元素。

2. 字符串处理

在通用的扁平化方法中,字符串会被分解为单个字符。如果不想处理字符串,可以在代码中添加过滤条件。

1
2
3
4
5
6
7
8
9
def flatten(itr):
if type(itr) in (str, bytes):
yield itr
else:
for x in itr:
try:
yield from flatten(x)
except TypeError:
yield x

3. 递归深度问题

使用递归方法处理深度嵌套的列表时,可能会导致递归深度过深,引发RecursionError。可以使用迭代方法来避免这个问题。

1
2
3
4
5
6
7
8
9
10
11
def _flatten(l):
stack = l.copy()
while stack:
item = stack.pop()
if isinstance(item, list):
stack.extend(item)
else:
yield item

def flatten(l):
return reversed(list(_flatten(l)))

如何将嵌套列表转换为扁平列表
https://119291.xyz/posts/2025-05-08.how-to-make-a-flat-list-out-of-a-list-of-lists/
作者
ww
发布于
2025年5月8日
许可协议