如何将一个列表的列表转换为扁平列表?

发布时间 2023-10-11 23:15:05作者: 小满独家

内容来自 DOC https://q.houxu6.top/?s=如何将一个列表的列表转换为扁平列表?

我有一个列表的列表,如下所示:

[
    [1, 2, 3],
    [4, 5, 6],
    [7],
    [8, 9]
]

如何将其展平以获得 [1, 2, 3, 4, 5, 6, 7, 8, 9]


如果您的列表的列表来自嵌套的列表推导式,可以通过修复推导式更简单/直接地解决问题;请参阅 如何从列表推导式中获得扁平结果而不是嵌套列表?

这里最常见的解决方案通常只展平一层嵌套的列表。有关完全展平深层嵌套结构(通常以递归方式)的解决方案,请参阅 Flatten an irregular (arbitrarily nested) list of lists


给定一个列表的列表 l

flat_list = [item for sublist in l for item in sublist]

这意味着:

flat_list = []
for sublist in l:
    for item in sublist:
        flat_list.append(item)

比迄今为止发布的快捷方式要快。(l 是要展平的列表。)

这是相应的函数:

def flatten(l):
    return [item for sublist in l for item in sublist]

您可以使用标准库中的 timeit 模块作为证据:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]\*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]\*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]\*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

解释:基于 + 的快捷方式(包括在 sum 中隐含的使用)在有 L个子列表时必然是 O(L**2)。因为中间结果列表的长度不断增加,每一步都会分配一个新的中间结果列表对象,并且之前的所有中间结果都必须被复制(以及在末尾添加一些新项)。因此,为了简化起见,不考虑实际的损失概括,假设你有 L个子列表,每个子列表包含 I 个项目:前 I 个项目需要来回 L-1 次复制,接下来的 I 个项目需要 L-2 次复制,依此类推;总的复制次数是 I 乘以从 1 到 L 的 x 的和,即 I * (L**2)/2

列表推导式只生成一次列表,并恰好将每个项目复制一次(从其原始位置传输到结果列表)。