使用Python脚本的过程中,偶尔需要使用list多层转一层
,又总是忘记怎么写搜索关键词,所以总是找了很久,现在把各种方法记录下来,方便自己也方便大家.
方法很多,现在就简单写8种,后面再对这8种方法做基准测试.
声明:文中的方法均收集自Making a flat list out of list of lists in Python
方法汇总1.定义减层方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import functoolsimport itertoolsimport numpyimport operatorimport perfplotfrom collections import Iterable from iteration_utilities import deepflattendef 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 itertools_chain (a ): return list (itertools.chain.from_iterable(a)) def numpy_flat (a ): return list (numpy.array(a).flat) def numpy_concatenate (a ): return list (numpy.concatenate(a)) 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 pylangs_flatten (a ): return list (flatten(a)) def iteration_utilities_deepflatten (a ): return list (deepflatten(a, depth=1 ))
2.测试
1 2 3 4 5 6 7 8 9 10 11 12 13 a=[[1 ,2 ,3 ],[4 ,5 ,6 ],[7 ,8 ,9 ]] print (a)print ('--------------------------' )print (forfor(a))print (sum_brackets(a))print (functools_reduce(a))print (itertools_chain(a))print (numpy_flat(a))print (numpy_concatenate(a))print (pylangs_flatten(a))print (iteration_utilities_deepflatten(a))
输出:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -------------------------- [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9]
各种方法的基准测试(消耗时间对比)各种方法在小数据上消耗时间差别不大,如果数据很小,没必要为了选择而烦恼,如果数据很大,可以参考下面基准测试的结果来选择减层方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import matplotlib.pyplot as pltfrom simple_benchmark import benchmarkb = benchmark( [forfor, sum_brackets, functools_reduce, itertools_chain,numpy_flat, numpy_concatenate, pylangs_flatten,iteration_utilities_deepflatten], arguments={2 **i: [[0 ]*5 ]*(2 **i) for i in range (1 , 13 )}, argument_name='number of inner lists' ) plt.subplots(1 ,1 ,figsize=(15 ,10 )) b.plot() plt.legend(loc = 'upper left' ) plt.show()
相同数据量,纵轴方向越小,方法越快.
代码可以从这里 下载,需要部署Jupyter环境,可参考我的博客部署方法.