如何在不使用 numpy 的情况下将 2D 列表展平为 1D? [英] how to flatten a 2D list to 1D without using numpy?

查看:31
本文介绍了如何在不使用 numpy 的情况下将 2D 列表展平为 1D?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

有没有不使用 numpy 的轻量级函数来做到这一点?

解决方案

没有 numpy ( ndarray.flatten ) 一种方法是使用 chain.from_iterable 这是 itertools.chain 的替代构造函数:

<预><代码>>>>列表(chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]]))[1, 2, 3, 1, 2, 1, 4, 5, 6, 7]

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

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

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

In [4]: from functools import reduce # Python3在 [5] 中:reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])输出[5]:[1, 2, 3, 1, 2, 1, 4, 5, 6, 7]

为了让它稍微快一点,您可以使用内置的 operator.add 代替 lambda:

In [6]: from operator import add在 [7] 中:reduce(add ,[[1,2,3],[1,2],[1,4,5,6,7]])输出[7]: [1, 2, 3, 1, 2, 1, 4, 5, 6, 7]在 [8]: %timeit reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])每个循环 789 ns ± 7.3 ns(7 次运行的平均值 ± 标准偏差,每次 1000000 次循环)在 [9]: %timeit reduce(add ,[[1,2,3],[1,2],[1,4,5,6,7]])每个循环 635 ns ± 4.38 ns(7 次运行的平均值 ± 标准偏差,每次 1000000 次循环)

基准:

:~$ python -m timeit "from itertools import chain;chain.from_iterable([[1,2,3],[1,2],[1,4,5,6,7]])"1000000 个循环,最好的 3 个:每个循环 1.58 微秒:~$ python -m timeit "reduce(lambda x,y :x+y ,[[1,2,3],[1,2],[1,4,5,6,7]])";1000000 个循环,最好的 3 个:每个循环 0.791 微秒:~$ python -m timeit "[j for i in [[1,2,3],[1,2],[1,4,5,6,7]] for j in i]";1000000 个循环,最好的 3 个:每个循环 0.784 微秒

使用 sum 的@Will 答案的基准(它对短名单来说很快,但对长名单来说不是很快):

:~$ python -m timeit "sum([[1,2,3],[4,5,6],[7,8,9]], [])";1000000 个循环,最好的 3 个:每个循环 0.575 微秒:~$ python -m timeit "sum([range(100),range(100)], [])";100000 个循环,最好的 3 个:每个循环 2.27 微秒:~$ python -m timeit "reduce(lambda x,y :x+y ,[range(100),range(100)])";100000 个循环,最好的 3 个:每个循环 2.1 usec

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]

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

解决方案

Without numpy ( ndarray.flatten ) one way would be using chain.from_iterable which is an alternate constructor for 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 :

[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 reduce in Python2 and functools.reduce in Python3 (don't use this for long lists):

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 can use operator.add, which is built-in, instead of 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) :

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

这篇关于如何在不使用 numpy 的情况下将 2D 列表展平为 1D?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆