如何在不使用numpy的情况下将2D列表展平为1D?

wak*_*ddy 27 python arrays numpy list

我有一个列表如下:

[[1,2,3],[1,2],[1,4,5,6,7]]
Run Code Online (Sandbox Code Playgroud)

我想把它弄平 [1,2,3,1,2,1,4,5,6,7]

没有使用numpy有这么轻的功能吗?

Kas*_*mvd 51

如果没有numpy(ndarray.flatten),您可以使用chain.from_iterable它作为替代构造函数itertools.chain:

>>> list(chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]]))
[1, 2, 3, 1, 2, 1, 4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

你也可以reduce在python 2和functools.reducein 3中使用对短列表更有效(不要将它用于长列表):

[j for sub in [[1,2,3],[1,2],[1,4,5,6,7]] for j in sub]
Run Code Online (Sandbox Code Playgroud)

或者作为另一种Pythonic方法,您可以使用列表理解:

In [4]: from functools import reduce # Python3

In [5]: reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])
Out[5]: [1, 2, 3, 1, 2, 1, 4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

风向标:

In [6]: from operator import add

In [7]: reduce(add ,[[1,2,3],[1,2],[1,4,5,6,7]])
Out[7]: [1, 2, 3, 1, 2, 1, 4, 5, 6, 7]

In [8]: %timeit reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])
789 ns ± 7.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [9]: %timeit reduce(add ,[[1,2,3],[1,2],[1,4,5,6,7]])
635 ns ± 4.38 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)

使用@Will的答案的基准operator.add(快速列表,但不是长列表):

:~$ python -m timeit "from itertools import chain;chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]])"
1000000 loops, best of 3: 1.58 usec per loop
:~$ python -m timeit "reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])"
1000000 loops, best of 3: 0.791 usec per loop
:~$ python -m timeit "[j for i in [[1,2,3],[1,2],[1,4,5,6,7]] for j in i]"
1000000 loops, best of 3: 0.784 usec per loop
Run Code Online (Sandbox Code Playgroud)

  • @Kasramvd很棒的回复!但是,我对如何为i中的j的`[j for i in [[1,2,3],[1,2],[1,4,5,6,7]]这样的非嵌套列表理解感到困惑]`可以使2D列表变平,您能再给出一些例证吗? (2认同)

wil*_*ill 35

对于这样的列表,我最喜欢的巧妙的小技巧就是使用sum;

sum有一个可选参数:sum(iterable [, start]),所以你可以这样做:

list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
print sum(list_of_lists, []) # [1,2,3,4,5,6,7,8,9]
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为+运算符恰好是列表的连接运算符,并且您已经告诉它起始值是[]- 一个空列表.

sum建议您使用的文件itertools.chain,因为它更清晰.

  • my_list看起来像`["A",["B","C"],"D",["E","F"]]`它不起作用, (3认同)
  • @pyd 它不起作用,因为“A”不是列表,但 ["B","C"] 是这样,当它尝试使用 + 连接它们时失败(您不能将字符串添加到列表中) (3认同)

Ale*_*yle 9

这将适用于您的特定情况。如果您有多层嵌套迭代,则递归函数效果最好。

def flatten(input):
    new_list = []
    for i in input:
        for j in i:
            new_list.append(j)
    return new_list
Run Code Online (Sandbox Code Playgroud)

  • 这是真正适用于深度嵌套列表的唯一解决方案。 (2认同)