如何从列表推导式获取扁平化结果而非嵌套列表?

118 投票
18 回答
96958 浏览
提问于 2025-04-15 12:39

我有一个列表 A,还有一个函数 f,这个函数可以接收 A 中的一个元素,并返回一个列表。我可以用列表推导式把 A 中的每个元素都处理一遍,比如 [f(a) for a in A],但这样会得到一个列表的列表。假设我的输入是 [a1,a2,a3],结果就会是 [[b11,b12],[b21,b22],[b31,b32]]

我该怎么做才能得到一个“扁平化”的列表 [b11,b12,b21,b22,b31,b32] 呢?换句话说,在 Python 中,怎么才能实现类似于函数式编程语言中的 flatmap,或者 .NET 中的 SelectMany 呢?

(在实际代码中,A 是一个目录的列表,而 fos.listdir。我想要构建一个包含所有子目录的扁平列表。)


另见: 如何将列表的列表变成扁平列表? 这是关于在创建后扁平化列表的一般问题。

18 个回答

73

你可以在itertools 的使用示例中找到一个很好的答案:

import itertools

def flatten(list_of_lists):
    return list(itertools.chain.from_iterable(list_of_lists))
96
>>> from functools import reduce  # not needed on Python 2
>>> list_of_lists = [[1, 2],[3, 4, 5], [6]]
>>> reduce(list.__add__, list_of_lists)
[1, 2, 3, 4, 5, 6]

这个 itertools 的解决方案 更高效,但这个方法看起来更符合 Python 的风格。

165

你可以在一个列表推导式中使用嵌套循环:

[filename for path in dirs for filename in os.listdir(path)]

这在功能上是等价于:

filenames = []
for path in dirs:
    for filename in os.listdir(path):
        filenames.append(filename)

撰写回答