以此为本,以此为本,以此为本,以此为本,以此为本,以此为本,以此为本。


如果您的列表来自列表理解,问题可以通过纠正理解更简单/直接解决;请参见Python列表理解;压缩列表?

在这里,最受欢迎的解决方案通常只包含一个“层”的清单。 查看清单不规则(自愿清单)的清单,解决方案完全清单一个深度清单的结构(重复,一般)。


当前回答

使用 functools.reduce,将积累的列表 xs 添加到下列列表 ys:

from functools import reduce
xss = [[1,2,3], [4,5,6], [7], [8,9]]
out = reduce(lambda xs, ys: xs + ys, xss)

出口:

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

使用 operator.concat 的更快方法:

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

出口:

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

其他回答

要插入深厚的数据结构,请使用 iteration_utilities.deepflatten1:

>>> from iteration_utilities import deepflatten

>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> list(deepflatten(l, depth=1))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

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

这是一个发电机,所以你需要将结果投到列表中,或者明确地对其进行调解。


要单一的平面,如果每一个项目本身是不可分割的,你也可以使用 iteration_utilities.flatten 它本身只是一个薄的旋转器周围 itertools.chain.from_iterable:

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

只需添加一些时间表(基于Nico Schlömer的答案,其中不包含此答案中的功能):

此分類上一篇

结果表明,如果 iterable 只包含几个内部 iterables 那么 总数将是最快的,但是,对于长期 iterables 只有 itertools.chain.from_iterable, iteration_utilities.deepflatten 或 nested 理解具有合理的性能, itertools.chain.from_iterable 是最快的(如 Nico Schlömer 已经注意到)。

from itertools import chain
from functools import reduce
from collections import Iterable  # or from collections.abc import Iterable
import operator
from iteration_utilities import deepflatten

def nested_list_comprehension(lsts):
    return [item for sublist in lsts for item in sublist]

def itertools_chain_from_iterable(lsts):
    return list(chain.from_iterable(lsts))

def pythons_sum(lsts):
    return sum(lsts, [])

def reduce_add(lsts):
    return reduce(lambda x, y: x + y, lsts)

def pylangs_flatten(lsts):
    return list(flatten(lsts))

def flatten(items):
    """Yield items from any nested iterable; see REF."""
    for x in items:
        if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
            yield from flatten(x)
        else:
            yield x

def reduce_concat(lsts):
    return reduce(operator.concat, lsts)

def iteration_utilities_deepflatten(lsts):
    return list(deepflatten(lsts, depth=1))


from simple_benchmark import benchmark

b = benchmark(
    [nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add,
     pylangs_flatten, reduce_concat, iteration_utilities_deepflatten],
    arguments={2**i: [[0]*5]*(2**i) for i in range(1, 13)},
    argument_name='number of inner lists'
)

b.plot()

1 Disclaimer:我是该图书馆的作者

考虑到列表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]

作为证据,您可以在标准图书馆中使用时间模块:

$ 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

解释:基于 + 的缩写(包括在总中使用)是必然的 O(L**2)当有 L 列表时 - 因为中间结果列表保持长,每个步骤都会分配一个新的中间结果列表对象,前中间结果中的所有对象都必须复制(以及在结尾添加一些新的对象)。

列表理解只产生一个列表,一次,并复制每个项目(从其原始居住地到结果列表)也准确一次。

你可以简单地使用Pandas这样做:

import pandas as pd
pd.Series([[1, 2, 3], [4, 5, 6], [7], [8, 9]]).sum()

我用 perfplot 测试了大多数建议的解决方案(我的宠物项目,基本上是时间周围的插槽),并发现

import functools
import operator
functools.reduce(operator.iconcat, a, [])

要成为最快的解决方案,无论是许多小列表还是很少的长列表都被混合(operator.iadd 同样快)。

更简单、更可接受的选择是

out = []
for sublist in a:
    out.extend(sublist)

如果字体列表的数量很大,这表现得比上面的建议略糟糕。

此分類上一篇

此分類上一篇


重复字符的代码:

import functools
import itertools
import operator

import numpy as np
import perfplot


def forfor(a):
    return [item for sublist in a for item in sublist]


def sum_brackets(a):
    return sum(a, [])


def functools_reduce(a):
    return functools.reduce(operator.concat, a)


def functools_reduce_iconcat(a):
    return functools.reduce(operator.iconcat, a, [])


def itertools_chain(a):
    return list(itertools.chain.from_iterable(a))


def numpy_flat(a):
    return list(np.array(a).flat)


def numpy_concatenate(a):
    return list(np.concatenate(a))


def extend(a):
    out = []
    for sublist in a:
        out.extend(sublist)
    return out


b = perfplot.bench(
    setup=lambda n: [list(range(10))] * n,
    # setup=lambda n: [list(range(n))] * 10,
    kernels=[
        forfor,
        sum_brackets,
        functools_reduce,
        functools_reduce_iconcat,
        itertools_chain,
        numpy_flat,
        numpy_concatenate,
        extend,
    ],
    n_range=[2 ** k for k in range(16)],
    xlabel="num lists (of length 10)",
    # xlabel="len lists (10 lists total)"
)
b.save("out.png")
b.show()

这对我来说似乎是最简单的:

>>> import numpy as np
>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> print(np.concatenate(l))
[1 2 3 4 5 6 7 8 9]