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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29244286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:16:13  来源:igfitidea点击:

how to flatten a 2D list to 1D without using numpy?

pythonarrayslistnumpy

提问by wakeupbuddy

I have a list looks like this:

我有一个看起来像这样的列表:

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

and I want to flatten it into [1,2,3,1,2,1,4,5,6,7]

我想把它压扁成 [1,2,3,1,2,1,4,5,6,7]

is there a light weight function to do this without using numpy?

是否有轻量级功能可以在不使用 numpy 的情况下执行此操作?

采纳答案by Kasramvd

Without numpy ( ndarray.flatten) one way would be using chain.from_iterablewhich is an alternate constructor for itertools.chain:

如果没有 numpy( ndarray.flatten),一种方法是使用 chain.from_iterablewhich 是 的替代构造函数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]

Or as another yet Pythonic approach you can use a list comprehension:

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

[j for sub in [[1,2,3],[1,2],[1,4,5,6,7]] for j in sub]

Another functional approach very suitable for short lists could also be reducein Python2 and functools.reducein Python3 (don't use it for long lists):

另一种非常适合短列表的函数式方法也可以reduce在 Python2 和functools.reducePython3 中使用(不要将它用于长列表):

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]

To make it slightly faster you could can use operator.add, which is built-in, instead of lambda:

为了使它稍微快一点,您可以使用operator.add内置的 ,而不是lambda

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)

benchmark:

基准:

:~$ 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

A benchmark on @Will's answer that used sum(its fast for short list but not for long list) :

使用的@Will 答案的基准测试sum(对于短名单而言很快,但对于长名单而言不是很快):

:~$ python -m timeit "sum([[1,2,3],[4,5,6],[7,8,9]], [])"
1000000 loops, best of 3: 0.575 usec per loop
:~$ python -m timeit "sum([range(100),range(100)], [])"
100000 loops, best of 3: 2.27 usec per loop
:~$ python -m timeit "reduce(lambda x,y :x+y ,[range(100),range(100)])"
100000 loops, best of 3: 2.1 usec per loop

回答by AlexMayle

This will work in your particular case. A recursive function would work best if you have multiple levels of nested iterables.

这将适用于您的特定情况。如果您有多个级别的嵌套可迭代对象,递归函数将最有效。

def flatten(input):
    new_list = []
    for i in input:
        for j in i:
            new_list.append(j)
    return new_list

回答by will

For just a list like this, my favourite neat little trick is just to use sum;

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

sumhas an optional argument: sum(iterable [, start]), so you can do:

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]

this works because the +operator happens to be the concatenation operator for lists, and you've told it that the starting value is []- an empty list.

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

but the documentaion for sumadvises that you use itertools.chaininstead, as it's much clearer.

但是文档sum建议您改用itertools.chain它,因为它更清晰。