如何从列表列表中制做平面列表?

我想知道是否有捷径能够从Python的列表清单中作出一个简单的清单。 html

我能够在for循环中执行此操做,可是也许有一些很酷的“单行代码”? 我用reduce()尝试过,可是出现错误。 app

ide

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'

#1楼

也能够使用NumPy的flatoop

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

编辑11/02/2016:仅当子列表具备相同尺寸时才可用。 性能


#2楼

彷佛与operator.add混淆了! 将两个列表加在一块儿时,正确的术语是concat ,而不是add。 operator.concat是您须要使用的。 测试

若是您认为功能正常,那么就这么简单: spa

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

您会看到reduce尊重序列类型,所以在提供元组时,您会获得一个元组。 让咱们尝试一个列表: code

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

啊哈,您会获得一个清单。 htm

性能如何:

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

#3楼

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]

#4楼

若是您愿意放弃一点速度以得到更干净的外观,则能够使用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.concatenatenumpy.ravel中找到更多信息


#5楼

上面的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]
相关文章
相关标签/搜索