我的列表如下:
[[1,2,3],[1,2],[1,4,5,6,7]]
我希望将其展平为[1,2,3,1,2,1,4,5,6,7]
有没有使用numpy的轻量级功能?
答案 0 :(得分:42)
如果没有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]
你也可以在python 2中使用reduce
,在3中使用functools.reduce
,这对于短列表更有效(不要将它用于长列表):
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]
或者稍微快一点的方法是使用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)
或者作为另一种Pythonic方法,您可以使用列表理解:
[j for sub in [[1,2,3],[1,2],[1,4,5,6,7]] for j in sub]
基准:
:~$ 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
使用sum
的@ Will的答案的基准(快速列表,但不是长列表):
:~$ 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
答案 1 :(得分:28)
对于这样的列表,我最喜欢的简洁小技巧就是使用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]
这是有效的,因为+
运算符恰好是列表的连接运算符,并且您已经告诉它起始值为[]
- 一个空列表。
但sum
的文档建议您使用itertools.chain
代替,因为它更清晰。
答案 2 :(得分:1)
这将适用于您的特定情况。如果您有多个级别的嵌套iterables,递归函数将最有效。
def flatten(input):
new_list = []
for i in input:
for j in i:
new_list.append(j)
return new_list