以此为本,以此为本,以此为本,以此为本,以此为本,以此为本,以此为本。


如果您的列表来自列表理解,问题可以通过纠正理解更简单/直接解决;请参见Python列表理解;压缩列表?

在这里,最受欢迎的解决方案通常只包含一个“层”的清单。 查看清单不规则(自愿清单)的清单,解决方案完全清单一个深度清单的结构(重复,一般)。


当前回答

对于包含多个列表的列表,这里是一个重复的解决方案,为我工作,我希望它是正确的:

# Question 4
def flatten(input_ls=[]) -> []:
    res_ls = []
    res_ls = flatten_recursive(input_ls, res_ls)

    print("Final flatten list solution is: \n", res_ls)

    return res_ls


def flatten_recursive(input_ls=[], res_ls=[]) -> []:
    tmp_ls = []

    for i in input_ls:
        if isinstance(i, int):
            res_ls.append(i)
        else:
            tmp_ls = i
            tmp_ls.append(flatten_recursive(i, res_ls))

    print(res_ls)
    return res_ls


flatten([0, 1, [2, 3], 4, [5, 6]])  # test
flatten([0, [[[1]]], [[2, 3], [4, [[5, 6]]]]])

出口:

[0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
Final flatten list solution is: 
 [0, 1, 2, 3, 4, 5, 6]
[0, 1]
[0, 1]
[0, 1]
[0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]
Final flatten list solution is: 
 [0, 1, 2, 3, 4, 5, 6]

其他回答

我想要一個解決方案,可以處理多種<unk>(<unk>,<unk>,<unk>,<unk>),<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>,<unk>。

这就是我所带来的:

def _flatten(l) -> Iterator[Any]:
    stack = l.copy()
    while stack:
        item = stack.pop()
        if isinstance(item, list):
            stack.extend(item)
        else:
            yield item


def flatten(l) -> Iterator[Any]:
    return reversed(list(_flatten(l)))

和测试:

@pytest.mark.parametrize('input_list, expected_output', [
    ([1, 2, 3], [1, 2, 3]),
    ([[1], 2, 3], [1, 2, 3]),
    ([[1], [2], 3], [1, 2, 3]),
    ([[1], [2], [3]], [1, 2, 3]),
    ([[1], [[2]], [3]], [1, 2, 3]),
    ([[1], [[[2]], [3]]], [1, 2, 3]),
])
def test_flatten(input_list, expected_output):
    assert list(flatten(input_list)) == expected_output

如果你愿意放弃一小量的速度,以便更清洁的外观,那么你可以使用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

您可以在文档中了解更多, numpy.concatenate 和 numpy.ravel。

使用 functools.reduce,将积累的列表 xs 添加到下列列表 ys:

from functools import reduce
xss = [[1,2,3], [4,5,6], [7], [8,9]]
out = reduce(lambda xs, ys: xs + ys, xss)

出口:

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

使用 operator.concat 的更快方法:

from functools import reduce
import operator
xss = [[1,2,3], [4,5,6], [7], [8,9]]
out = reduce(operator.concat, xss)

出口:

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

注意: 下面适用于 Python 3.3+ 因为它使用 yield_from. six 也是第三方包,尽管它是稳定的。


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

但是,考虑这个稍微复杂的案例:

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

这里有几个问题:

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

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

在这里,您可以检查(一)的子元素(一)与(一)的Iterable(一)无效,从(一)的ABC,但也希望确保(二)的元素(一)不是“类似于(一)的”。

np.hstack(listoflist).tolist()