我想知道是否有一种快捷方式可以在Python中从列表列表中创建一个简单的列表。
我可以在for循环中这样做,但是也许有一些很酷的"一行代码"?我用reduce试过了,但是我得到了一个错误。
代码
1 2 | l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] reduce(lambda x, y: x.extend(y), l) |
错误消息
1 2 3 4 | Traceback (most recent call last): File"<stdin>", line 1, in <module> File"<stdin>", line 1, in <lambda> AttributeError: 'NoneType' object has no attribute 'extend' |
给定一个列表列表
这意味着:
1 2 3 4 | flat_list = [] for sublist in l: for item in sublist: flat_list.append(item) |
比目前发布的快捷方式更快。(
对应函数如下:
1 | flatten = lambda l: [item for sublist in l for item in sublist] |
作为证据,您可以使用标准库中的
1 2 3 4 5 6 | $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]' 10000 loops, best of 3: 143 usec per loop $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])' 1000 loops, best of 3: 969 usec per loop $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)' 1000 loops, best of 3: 1.1 msec per loop |
解释:基于
列表理解只生成一个列表,一次,并将每个项目复制一次(从其原始居住地到结果列表)。
您可以使用
1 2 3 | >>> import itertools >>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> merged = list(itertools.chain(*list2d)) |
或者,在Python >=2.6上使用
1 2 3 | >>> import itertools >>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> merged = list(itertools.chain.from_iterable(list2d)) |
这种方法比
1 2 3 4 5 6 7 8 9 10 | [me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))' 10000 loops, best of 3: 24.2 usec per loop [me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]' 10000 loops, best of 3: 45.2 usec per loop [me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])' 1000 loops, best of 3: 488 usec per loop [me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)' 1000 loops, best of 3: 522 usec per loop [me@home]$ python --version Python 2.7.3 |
作者注:这是低效的。但有趣的是,因为独角兽非常棒。它不适用于生产Python代码。
1 2 | >>> sum(l, []) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
这只是对第一个参数中传递的iterable的元素进行求和,将第二个参数作为求和的初始值(如果没有给出,则使用
因为要对嵌套列表求和,所以实际上得到的结果是
注意,只对列表中的列表有效。对于列表的列表的列表,您需要另一个解决方案。
我使用perfplot(我的一个宠物项目,本质上是一个围绕
1 | functools.reduce(operator.iconcat, a, []) |
成为最快的解决方案。(
再现图像的程式码:
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 | import functools import itertools import numpy import operator import perfplot def 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 functools_reduce_iconcat(a): return functools.reduce(operator.iconcat, 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)) perfplot.show( setup=lambda n: [list(range(10))] * n, kernels=[ forfor, sum_brackets, functools_reduce, functools_reduce_iconcat, itertools_chain, numpy_flat, numpy_concatenate ], n_range=[2**k for k in range(16)], logx=True, logy=True, xlabel='num lists' ) |
1 2 3 4 5 | from functools import reduce #python 3 >>> l = [[1,2,3],[4,5,6], [7], [8,9]] >>> reduce(lambda x,y: x+y,l) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
示例中的
执行
1 2 3 4 | >>> import operator >>> l = [[1,2,3],[4,5,6], [7], [8,9]] >>> reduce(operator.concat, l) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
下面是一种适用于数字、字符串、嵌套列表和混合容器的通用方法。
代码
1 2 3 4 5 6 7 8 9 10 11 | from collections import Iterable def flatten(items): """Yield items from any nested iterable; see Reference.""" for x in items: if isinstance(x, Iterable) and not isinstance(x, (str, bytes)): for sub_x in flatten(x): yield sub_x else: yield x |
注意:在python3中,
演示
1 2 3 4 5 6 7 | lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] list(flatten(lst)) # nested lists # [1, 2, 3, 4, 5, 6, 7, 8, 9] mixed = [[1, [2]], (3, 4, {5, 6}, 7), 8,"9"] # numbers, strs, nested & mixed list(flatten(mixed)) # [1, 2, 3, 4, 5, 6, 7, 8, '9'] |
参考
这个解决方案是从Beazley, D.和B. Jones的食谱中修改而来的。食谱4.14,Python烹饪书第三版,O'Reilly Media Inc.。塞瓦斯托波尔,CA: 2013。发现较早的SO帖子,可能是最初的演示。我收回我的话。sum不是赢家。虽然当列表很小的时候会更快。但是随着列表的增大,性能会显著下降。
1 2 3 4 5 | >>> timeit.Timer( '[item for sublist in l for item in sublist]', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10000' ).timeit(100) 2.0440959930419922 |
sum版本仍然运行了超过一分钟,还没有完成处理!
媒体列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> timeit.Timer( '[item for sublist in l for item in sublist]', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10' ).timeit() 20.126545906066895 >>> timeit.Timer( 'reduce(lambda x,y: x+y,l)', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10' ).timeit() 22.242258071899414 >>> timeit.Timer( 'sum(l, [])', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10' ).timeit() 16.449732065200806 |
使用小列表和时间:number=1000000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> timeit.Timer( '[item for sublist in l for item in sublist]', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]' ).timeit() 2.4598159790039062 >>> timeit.Timer( 'reduce(lambda x,y: x+y,l)', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]' ).timeit() 1.5289170742034912 >>> timeit.Timer( 'sum(l, [])', 'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]' ).timeit() 1.0598428249359131 |
如果您想使一个数据结构变平,而又不知道它嵌套的深度,您可以使用
1 2 3 4 5 6 7 8 9 | >>> from iteration_utilities import deepflatten >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> list(deepflatten(l, depth=1)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]] >>> list(deepflatten(l)) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
它是一个生成器,因此您需要将结果转换为
如果每一个项目本身是可迭代的,你也可以使用
1 2 3 4 | >>> from iteration_utilities import flatten >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> list(flatten(l)) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
只是添加一些时间(基于Nico Schl?未包含本答案中所述功能的mer答案):
它是一个对数-对数图,以适应跨越的值的巨大范围。定性推理:越低越好。
结果表明,如果迭代器只包含几个内部迭代器,那么
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 | from itertools import chain from functools import reduce from collections import Iterable # or from collections.abc import Iterable import operator from iteration_utilities import deepflatten def nested_list_comprehension(lsts): return [item for sublist in lsts for item in sublist] def itertools_chain_from_iterable(lsts): return list(chain.from_iterable(lsts)) def pythons_sum(lsts): return sum(lsts, []) def reduce_add(lsts): return reduce(lambda x, y: x + y, lsts) def pylangs_flatten(lsts): return list(flatten(lsts)) 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 reduce_concat(lsts): return reduce(operator.concat, lsts) def iteration_utilities_deepflatten(lsts): return list(deepflatten(lsts, depth=1)) from simple_benchmark import benchmark b = benchmark( [nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add, pylangs_flatten, reduce_concat, iteration_utilities_deepflatten], arguments={2**i: [[0]*5]*(2**i) for i in range(1, 13)}, argument_name='number of inner lists' ) b.plot() |
免责声明:我是那个图书馆的作者
为什么要使用extend?
1 | reduce(lambda x, y: x+y, l) |
这应该没问题。
似乎与
如果你认为功能,它是这样简单::
1 2 3 | >>> list2d = ((1, 2, 3), (4, 5, 6), (7,), (8, 9)) >>> reduce(operator.concat, list2d) (1, 2, 3, 4, 5, 6, 7, 8, 9) |
您将看到reduce尊重序列类型,因此当您提供一个元组时,您将返回一个元组。让我们试着用一个列表::
1 2 3 | >>> list2d = [[1, 2, 3],[4, 5, 6], [7], [8, 9]] >>> reduce(operator.concat, list2d) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
啊哈,你得到了一个列表。
如何表现::
1 2 3 | >>> list2d = [[1, 2, 3],[4, 5, 6], [7], [8, 9]] >>> %timeit list(itertools.chain.from_iterable(list2d)) 1000000 loops, best of 3: 1.36 μs per loop |
from_iterable非常快!但与concat相比没有可比性。
1 2 3 | >>> list2d = ((1, 2, 3),(4, 5, 6), (7,), (8, 9)) >>> %timeit reduce(operator.concat, list2d) 1000000 loops, best of 3: 492 ns per loop |
您的函数不能工作的原因:extend extends array in-place并没有返回它。你仍然可以从返回x,使用一些技巧:
1 | reduce(lambda x,y: x.extend(y) or x, l) |
注意:扩展比列表中的+更有效。
考虑安装
1 | > pip install more_itertools |
它附带了
1 2 3 4 5 6 | import more_itertools lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] list(more_itertools.flatten(lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9] |
从2.4版开始,您可以使用
1 2 3 4 5 6 7 | lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] list(more_itertools.collapse(lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9] lst = [[1, 2, 3], [[4, 5, 6]], [[[7]]], 8, 9] # complex nesting list(more_itertools.collapse(lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9] |
1 2 3 4 5 6 7 8 9 10 11 | def flatten(l, a): for i in l: if isinstance(i, list): flatten(i, a) else: a.append(i) return a print(flatten([[[1, [1,1, [3, [4,5,]]]], 2, 3], [4, 5],6], [])) # [1, 1, 1, 3, 4, 5, 2, 3, 4, 5, 6] |
上面Anil函数的一个不好的特性是,它要求用户总是手动指定第二个参数为空列表
这是一个工作函数:
1 2 3 4 5 6 7 8 9 10 11 12 | def list_flatten(l, a=None): #check a if a is None: #initialize with empty list a = [] for i in l: if isinstance(i, list): list_flatten(i, a) else: a.append(i) return a |
测试:
1 2 3 4 5 6 7 | In [2]: lst = [1, 2, [3], [[4]],[5,[6]]] In [3]: lst Out[3]: [1, 2, [3], [[4]], [5, [6]]] In [11]: list_flatten(lst) Out[11]: [1, 2, 3, 4, 5, 6] |
下面这些对我来说似乎是最简单的:
1 2 3 4 | >>> import numpy as np >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> print (np.concatenate(l)) [1 2 3 4 5 6 7 8 9] |
在处理基于文本的可变长度列表时,接受的答案对我不起作用。这里有一个对我有用的替代方法。
1 | l = ['aaa', 'bb', 'cccccc', ['xx', 'yyyyyyy']] |
接受了无效的答案:
1 2 3 | flat_list = [item for sublist in l for item in sublist] print(flat_list) ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'xx', 'yyyyyyy'] |
新提出的解决方案,为我工作:
1 2 3 4 | flat_list = [] _ = [flat_list.extend(item) if isinstance(item, list) else flat_list.append(item) for item in l if item] print(flat_list) ['aaa', 'bb', 'cccccc', 'xx', 'yyyyyyy'] |
1 2 3 4 5 | import matplotlib l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] print(list(matplotlib.cbook.flatten(l))) l2 = [[1, 2, 3], [4, 5, 6], [7], [8, [9, 10, [11, 12, [13]]]]] print list(matplotlib.cbook.flatten(l2)) |
结果:
1 2 | [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] |
这比underscore._.flatten快18倍:
1 2 3 | Average time over 1000 trials of matplotlib.cbook.flatten: 2.55e-05 sec Average time over 1000 trials of underscore._.flatten: 4.63e-04 sec (time for underscore._)/(time for matplotlib.cbook) = 18.1233394636 |
你也可以使用NumPy's flat:
1 2 | import numpy as np list(np.array(l).flat) |
编辑11/02/2016:只有当子列表具有相同的维度时才有效。
您可以使用numpy:
递归版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | x = [1,2,[3,4],[5,[6,[7]]],8,9,[10]] def flatten_list(k): result = list() for i in k: if isinstance(i,list): #The isinstance() function checks if the object (first argument) is an #instance or subclass of classinfo class (second argument) result.extend(flatten_list(i)) #Recursive call else: result.append(i) return result flatten_list(x) #result = [1,2,3,4,5,6,7,8,9,10] |
1 2 3 4 5 6 7 | def flatten(alist): if alist == []: return [] elif type(alist) is not list: return [alist] else: return flatten(alist[0]) + flatten(alist[1:]) |
简单的代码为
1 2 3 | from underscore import _ _.flatten([[1, 2, 3], [4, 5, 6], [7], [8, 9]]) # [1, 2, 3, 4, 5, 6, 7, 8, 9] |
它解决了所有的平面问题(没有列表项或复杂嵌套)
1 2 3 4 5 | from underscore import _ # 1 is none list item # [2, [3]] is complex nesting _.flatten([1, [2, [3]], [4, 5, 6], [7], [8, 9]]) # [1, 2, 3, 4, 5, 6, 7, 8, 9] |
您可以使用pip安装
1 | pip install underscore.py |
如果你愿意为了更干净的外观而牺牲一点速度,那么你可以使用
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99 %timeit numpy.concatenate(l).ravel().tolist() 1000 loops, best of 3: 313 μs per loop %timeit numpy.concatenate(l).tolist() 1000 loops, best of 3: 312 μs per loop %timeit [item for sublist in l for item in sublist] 1000 loops, best of 3: 31.5 μs per loop |
您可以在文档numpy中找到更多信息。连接和numpy.ravel
另一种不同寻常的方法适用于异质和齐次整数列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from typing import List def flatten(l: list) -> List[int]: """Flatten an arbitrary deep nested list of lists of integers. Examples: >>> flatten([1, 2, [1, [10]]]) [1, 2, 1, 10] Args: l: Union[l, Union[int, List[int]] Returns: Flatted list of integer """ return [int(i.strip('[ ]')) for i in str(l).split(',')] |
我找到的最快的解决方案(无论如何对于大列表):
1 2 3 | import numpy as np #turn list into an array and flatten() np.array(l).flatten() |
完成了!你当然可以通过执行list(l)把它变成一个列表
1 2 3 | flat_list = [] for i in list_of_list: flat_list+=i |
这段代码也可以很好地工作,因为它只是一直扩展列表。虽然非常相似,但只有一个for循环。所以它的复杂度比添加2 for循环要小。
一个简单的递归方法使用
1 2 3 4 5 | >>> from functools import reduce >>> from operator import add >>> flatten = lambda lst: [lst] if type(lst) is int else reduce(add, [flatten(ele) for ele in lst]) >>> flatten(l) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
函数
递归不同于
1 2 3 | >>> l2 = [[3, [1, 2], [[[6], 5], 4, 0], 7, [[8]], [9, 10]]] >>> flatten(l2) [3, 1, 2, 6, 5, 4, 0, 7, 8, 9, 10] |
这可能不是最有效的方法,但我想放一行(实际上是两行)。两个版本都可以在任意层次嵌套列表上工作,并利用语言特性(Python3.5)和递归。
1 2 3 4 5 6 7 8 | def make_list_flat (l): flist = [] flist.extend ([l]) if (type (l) is not list) else [flist.extend (make_list_flat (e)) for e in l] return flist a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]] flist = make_list_flat(a) print (flist) |
输出是
1 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] |
这是以深度优先的方式工作的。递归一直向下,直到找到一个非列表元素,然后扩展局部变量
上面的一个创建了几个本地列表并返回它们,这些列表用于扩展父列表。我认为解决这个问题的方法可能是创建一个gloabl
1 2 3 4 5 6 7 | a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]] flist = [] def make_list_flat (l): flist.extend ([l]) if (type (l) is not list) else [make_list_flat (e) for e in l] make_list_flat(a) print (flist) |
输出也是
1 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] |
虽然我不确定这个时候的效率。
注意:下面的代码适用于Python 3.3+,因为它使用
对于
然而,考虑一下这个稍微复杂一点的情况:
1 | >>> obj = [[1, 2, 3], [4, 5], 6, 'abc', [7], [8, [9, 10]]] |
这里有几个问题:
一个元素,你可以补救如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> from collections import Iterable >>> from six import string_types >>> def flatten(obj): ... for i in obj: ... if isinstance(i, Iterable) and not isinstance(i, string_types): ... yield from flatten(i) ... else: ... yield i >>> list(flatten(obj)) [1, 2, 3, 4, 5, 6, 'abc', 7, 8, 9, 10] |
在这里,您检查子元素(1)是否可以使用
最近,我遇到了一种情况,在子列表中混合了字符串和数字数据,比如
1 2 3 4 5 6 7 8 9 10 11 | test = ['591212948', ['special', 'assoc', 'of', 'Chicago', 'Jon', 'Doe'], ['Jon'], ['Doe'], ['fl'], 92001, 555555555, 'hello', ['hello2', 'a'], 'b', ['hello33', ['z', 'w'], 'b']] |
像
1 2 3 4 5 6 7 8 9 | def concatList(data): results = [] for rec in data: if type(rec) == list: results += rec results = concatList(results) else: results.append(rec) return results |
结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | In [38]: concatList(test) Out[38]: Out[60]: ['591212948', 'special', 'assoc', 'of', 'Chicago', 'Jon', 'Doe', 'Jon', 'Doe', 'fl', 92001, 555555555, 'hello', 'hello2', 'a', 'b', 'hello33', 'z', 'w', 'b'] |
使用实际堆栈数据结构可以非常简单地避免对堆栈的递归调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | alist = [1,[1,2],[1,2,[4,5,6],3,"33"]] newlist = [] while len(alist) > 0 : templist = alist.pop() if type(templist) == type(list()) : while len(templist) > 0 : temp = templist.pop() if type(temp) == type(list()) : for x in temp : templist.append(x) else : newlist.append(temp) else : newlist.append(templist) print(list(reversed(newlist))) |
我们可以使用python的基本概念来做同样的事情
1 2 3 4 5 6 7 8 9 10 11 | nested_list=[10,20,[30,40,[50]],[80,[10,[20]],90],60] flat_list=[] def unpack(list1): for item in list1: try: len(item) unpack(item) except: flat_list.append(item) unpack(nested_list) print (flat_list) |
清理了@Deleet示例
1 2 3 4 5 6 7 8 9 10 11 12 13 | from collections import Iterable def flatten(l, a=[]): for i in l: if isinstance(i, Iterable): flatten(i, a) else: a.append(i) return a daList = [[1,4],[5,6],[23,22,234,2],[2], [ [[1,2],[1,2]],[[11,2],[11,22]] ] ] print(flatten(daList)) |
例如:https://repl.it/G8mb/0
这可以使用
1 2 3 | from cytoolz import concat l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] list(concat(l)) # or just `concat(l)` if one only wants to iterate over the items |
在我的电脑上,在python 3.6中,这个时间看起来几乎和
1 2 3 4 5 6 7 8 9 10 11 | In [611]: %timeit L = [item for sublist in l for item in sublist] 695 ns ± 2.75 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [612]: %timeit L = [item for sublist in l for item in sublist] 701 ns ± 5.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [613]: %timeit L = list(concat(l)) 719 ns ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [614]: %timeit L = list(concat(l)) 719 ns ± 22.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) |
1 2 3 4 5 6 7 | In [618]: from toolz import concat In [619]: %timeit L = list(concat(l)) 845 ns ± 29 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [620]: %timeit L = list(concat(l)) 833 ns ± 8.73 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) |
您可以使用chain类
输出将是:[A B C D E F]
参考:https://docs.python.org/2/library/itertools.html # itertools.chain
这适用于嵌套列表。它可以很容易地扩展到使用其他类型的迭代器。
1 2 3 4 5 6 7 8 9 | def flatten(seq): """list -> list return a flattend list from an abitrarily nested list """ if not seq: return seq if not isinstance(seq[0], list): return [seq[0]] + flatten(seq[1:]) return flatten(seq[0]) + flatten(seq[1:]) |
样本运行
1 2 | >>> flatten([1, [2, 3], [[[4, 5, 6], 7], [[8]]], 9]) [1, 2, 3, 4, 5, 6, 7, 8, 9] |
使用列表理解:
1 | mylist = [item for sublist in l for item in sublist] |
我认为最简单和通用的方法是这样写递归函数:
1 2 3 4 5 6 7 8 9 10 11 | def flat_list(some_list = []): elements=[] for item in some_list: if type(item) == type([]): elements += flat_list(item) else: elements.append(item) return elements list = ['a', 'b', 1, 2, 3, [1, 2, 3, 'c',[112,123,111,[1234,1111,3333,44444]]]] flat_list(list) |
吗?