提问



我想知道是否有一条快捷方式可以在Python列表中列出一个简单的列表。


我可以在for循环中做到这一点,但也许有一些很酷的单行?我用 reduce 尝试了,但是我收到了一个错误。


代码


l = [**1, 2, 3], [4, 5, 6], [7], [8, 9**]
reduce(lambda x, y: x.extend(y), l)


错误消息


Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'extend'

最佳参考


flat_list = [item for sublist in l for item in sublist]


意思是:


for sublist in l:
    for item in sublist:
        flat_list.append(item)


比目前发布的快捷方式快。 (l是要变平的名单。)


这是一个相应的功能:


flatten = lambda l: [item for sublist in l for item in sublist]


为了证据,一如既往,您可以使用标准库中的timeit模块:


$ 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


说明:当存在L个子列表时,基于+的快捷方式(包括sum中的隐含用法)必然是O(L**2) - 因为中间结果列表不断变长,每个步骤都会分配一个新的中间结果列表对象,并且必须复制前一个中间结果中的所有项目(以及最后添加的一些新项目)。所以(为了简单而没有实际的失去一般性)说你有每个项目的L个子列表:第一个I项目来回复制L-1次,第二个I项目L-2次,依此类推;总拷贝数是I乘以x的总和,从1到L排除,即I * (L**2)/2


列表理解只生成一个列表一次,并将每个项目(从其原始居住地点到结果列表)复制一次。

其它参考1


你可以用itertools.chain():[126]


>>> import itertools
>>> list2d = [**1,2,3],[4,5,6], [7], [8,9**]
>>> merged = list(itertools.chain(*list2d))


或者,在Python>=2.6时,使用itertools.chain.from_iterable(),它不需要解压缩列表:[127]


>>> import itertools
>>> list2d = [**1,2,3],[4,5,6], [7], [8,9**]
>>> merged = list(itertools.chain.from_iterable(list2d))


这种方法可以说比[item for sublist in l for item in sublist]更具可读性,并且看起来也更快:


[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

其它参考2


作者注意:效率低下。但很有趣,因为单子很棒。它不适合生产Python代码。


>>> sum(l, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]


这只是在第一个参数中传递的iterable元素的总和,将第二个参数视为总和的初始值(如果没有给出,则使用0代替,这种情况会给你一个错误)。


因为你是对嵌套列表求和,实际得到[1,3]+[2,4]作为sum([**1,3],[2,4**],[])的结果,它等于[1,3,2,4]


请注意,仅适用于列表列表。对于列表列表,您将需要另一个解决方案。

其它参考3


我用perfplot测试了大多数建议的解决方案(我的宠物项目,基本上是timeit的包装),并发现[128]




list(itertools.chain.from_iterable(a))


成为最快的解决方案(如果连接的列表超过10个)。


[129]





重现情节的代码:




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 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, itertools_chain, numpy_flat,
        numpy_concatenate
        ],
    n_range=[2**k for k in range(16)],
    logx=True,
    logy=True,
    xlabel='num lists'
    )

其它参考4


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]


示例中的extend()方法修改x而不是返回有用的值(reduce()期望的值)。


reduce版本的更快捷的方法是


>>> 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]

其它参考5


以下是适用于数字字符串嵌套列表和混合容器的一般方法。


代码


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


注意:在Python 3中,yield from flatten(x)可以替换for sub_x in flatten(x): yield sub_x


演示


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 Cookbook 3rd Ed。,OReilly Media Inc. Sebastopol,CA:2013。

  • 发现了早期的SO帖子,可能是最初的演示。


其它参考6


我接受我的陈述。总和不是赢家。虽然列表很小但速度更快。但是,随着更大的列表,性能会显着下降。


>>> 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


总和版本仍然运行超过一分钟,它还没有完成处理!


对于中型名单:


>>> 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


使用小列表和timeit:number=1000000


>>> 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

其它参考7


为什么使用extend?


reduce(lambda x, y: x+y, l)


这应该工作正常。

其它参考8


似乎与operator.add混淆了!当您将两个列表一起添加时,正确的术语是concat,而不是添加。 operator.concat是你需要使用的。


如果您正在思考功能,它就像这样容易::


>>> list2d = ((1,2,3),(4,5,6), (7,), (8,9))
>>> reduce(operator.concat, list2d)
(1, 2, 3, 4, 5, 6, 7, 8, 9)


你看到reduce尊重序列类型,所以当你提供一个元组时,你会得到一个元组。让我们尝试一下清单::


>>> list2d = [**1,2,3],[4,5,6], [7], [8,9**]
>>> reduce(operator.concat, list2d)
[1, 2, 3, 4, 5, 6, 7, 8, 9]


啊哈,你得到一份清单。


性能怎么样::


>>> 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减少它是没有可比性的。


>>> list2d = ((1,2,3),(4,5,6), (7,), (8,9))
>>> %timeit reduce(operator.concat, list2d)
1000000 loops, best of 3: 492 ns per loop

其它参考9


如果你想展平一个你不知道嵌套有多深的数据结构,你可以使用iteration_utilities.deepflatten 1 [131]


>>> 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]


它是一个生成器,因此您需要将结果转换为list或显式迭代它。





要展平一个级别,如果每个项目本身都是可迭代的,你也可以使用iteration_utilities.flatten,它本身只是itertools.chain.from_iterable的一个薄包装:[132] [133]


>>> 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]





只是为了添加一些时间(基于NicoSchlömer的答案,该答案不包括此答案中提供的功能):


[134]


它是一个对数 - 对数图,可以适应范围广泛的值。对于定性推理:越低越好。


结果表明,如果迭代只包含几个内部迭代,那么sum将是最快的,但是对于长迭代,只有itertools.chain.from_iterableiteration_utilities.deepflatten或嵌套理解具有sum的合理性能[[itertools.chain.from_iterable是最快的(正如NicoSchlömer已经注意到的那样)。


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()





1免责声明:我是该图书馆的作者

其它参考10


你的函数不起作用的原因:扩展扩展数组到位并且不返回它。你仍然可以使用一些技巧从lambda返回x:


reduce(lambda x,y: x.extend(y) or x, l)


注意:extend比列表上的+更有效。

其它参考11


考虑安装more_itertools包。[135]


> pip install more_itertools


它附带flatten的实现(来源,来自itertools食谱):[136] [137] [138]


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开始,你可以使用more_itertools.collapse(源代码,由abarnet贡献)来展平更复杂的嵌套迭代。[139] [140]


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]

其它参考12


上面Anil函数的一个不好的特性就是它要求用户总是手动指定第二个参数为空列表[]。这应该是默认值。由于Python对象的工作方式,这些应该是在函数内部设置,而不是在参数中。


这是一个有效的功能:


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


测试:


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]

其它参考13


以下对我来说似乎最简单:


>>> 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]

其它参考14


人们也可以使用NumPy的公寓:[141]


import numpy as np
list(np.array(l).flat)


编辑11/02/2016:仅当子列表具有相同的尺寸时才有效。

其它参考15


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]

其它参考16


underscore.py包风扇[142]的简单代码


from underscore import _
_.flatten([**1, 2, 3], [4, 5, 6], [7], [8, 9**])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]


它解决了所有展平问题(无列表项或复杂嵌套)


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 [143]安装underscore.py


pip install underscore.py

其它参考17


matplotlib.cbook.flatten()将适用于嵌套列表,即使它们比示例更深入嵌套。


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, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]


这比下划线快18倍._。flatten:


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

其它参考18


def flatten(alist):
    if alist == []:
        return []
    elif type(alist) is not list:
        return [alist]
    else:
        return flatten(alist[0]) + flatten(alist[1:])

其它参考19


如果你愿意放弃一点点速度以获得更清除的外观,那么你可以使用numpy.concatenate().tolist()numpy.concatenate().ravel().tolist():


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


您可以在docs numpy.concatenate和numpy.ravel [144] [145]中找到更多信息。

其它参考20


我找到的最快的解决方案(无论如何都是大型列表):


import numpy as np
#turn list into an array and flatten()
np.array(l).flatten()


完成!您当然可以通过执行list(l)将其转回列表

其它参考21


我最近遇到过一种情况,即我在子列表中混合了字符串和数字数据


test = ['591212948',
['special', 'assoc', 'of', 'Chicago', 'Jon', 'Doe'],
['Jon'],
['Doe'],
['fl'],
92001,
555555555,
'hello',
['hello2', 'a'],
'b',
['hello33', ['z', 'w'], 'b'**]


flat_list = [item for sublist in test for item in sublist]这样的方法没有用。所以,我提出了以下1+级别子列表的解决方案


def concatList(data):
    results = []
    for rec in data:
        if type(rec) == list:
            results += rec
            results = concatList(results)
        else:
            results.append(rec)
    return results


结果


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']

其它参考22


注意:以下内容适用于Python 3.3+,因为它使用yield_fromsix也是第三方包,但它是稳定的。或者,您可以使用sys.version[146]





obj = [**1, 2,], [3, 4], [5, 6**]的情况下,这里的所有解决方案都很好,包括列表理解和itertools.chain.from_iterable


但是,请考虑这个稍微复杂的情况:


>>> obj = [**1, 2, 3], [4, 5], 6, 'abc', [7], [8, [9, 10**]]


这里有几个问题:



  • 一个元素,6,只是一个标量;它不可迭代,所以上述路线将在这里失败。

  • 一个元素,'abc',在技术上是可迭代的(所有str都是)。但是,在线之间阅读一点,你不想这样对待它 - 你想把它当作一个单独的元素。

  • 最后一个元素[8, [9, 10**]本身就是一个嵌套的可迭代元素。基本列表理解和chain.from_iterable仅提取1级向下。



您可以按如下方式解决此问题:


>>> 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)是否可以Iterable迭代,itertools中的ABC,但也要确保(2)元素不 线状。[147]

其它参考23


flat_list = []
for i in list_of_list:
    flat_list+=i


此代码也可以正常工作,因为它只是一直扩展列表。虽然它非常相似,但只有一个用于循环。因此它比为循环添加2更少复杂。

其它参考24


您可以非常简单地使用实际的堆栈数据结构来避免对堆栈的递归调用。


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)))

其它参考25


另一种适用于异构和同类整数列表的不寻常方法:


def unusual_flatten(some_list: list) -> list:
    cleaned_list = str(some_list).replace(("["), "").replace("]", "").split(",")
    return [int(item) for item in cleaned_list]


应用示例列表...


l = [**1, 2, 3], [4, 5, 6], [7], [8, 9], 10]

unusual_flatten(l)


结果:


[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

其它参考26


这可能不是最有效的方式,但我想放一个单线(实际上是一个双线)。两个版本都可以在任意层次结构嵌套列表上运行,并利用语言功能(Python3.5)和递归。


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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]


这首先是深度工作。递归向下直到找到非列表元素,然后扩展局部变量flist,然后将其回滚到父级。每当返回flist时,它将扩展到列表推导中的父[[s flist。因此,在根处返回一个平面列表。


上面的一个创建了几个本地列表并返回它们,这些列表用于扩展父列表。我认为解决这个问题的方法可能是创建一个全局flist,如下所示。


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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]


虽然我现在还不确定效率。

其它参考27


清理@Deleet示例


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 [148]

其它参考28


这可以使用toolz.concatcytoolz.concat(cythonized版本,在某些情况下可能更快)来完成:[149]


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中,这似乎几乎和[item for sublist in l for item in sublist]一样快(不计入导入时间):


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)


toolz版本确实较慢:


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)

其它参考29


我们也可以这样做,使用python的基本概念


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)