部分列表在Python中展平

时间:2017-08-04 09:12:42

标签: python list

我有一个小问题,我缺乏一些Python经验。 假设一个清单:

list=[[40, 20, 45, 40], [[20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]]

我想做一些我称之为“部分扁平化”的事情。因为预期的输出是:

[[40, 20, 45, 40], [20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]

list的{​​{1}}之前注意,而预期输出的长度为2。问题是我事先并不知道3中哪个元素嵌套了一层。

This answer和许多其他人没有多大帮助,因为扁平化走得很远。在问题之后输出是:

list

(注意列表中前4个元素的缺失括号。

2 个答案:

答案 0 :(得分:1)

您可以创建一个递归函数,测试all内部元素是否为列表。如果是这样,则递归地应用算法,否则产生列表本身。

def inner_lists(lst):
    if all(isinstance(x, list) for x in lst):
        for inner in lst:
            for x in inner_lists(inner):
                yield x
    else:
        yield lst

>>> lst = [[40, 20, 45, 40], [[20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]]
>>> list(inner_lists(lst))
[[40, 20, 45, 40], [20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]

或使用yield from(Python 3.3及更高版本):

def inner_lists(lst):
    if all(isinstance(x, list) for x in lst):
        yield from (x for inner in lst for x in inner_lists(inner))
    else:
        yield lst

或没有发电机:

def inner_lists(lst):
    if all(isinstance(x, list) for x in lst):
        return [x for inner in lst for x in inner_lists(inner)]
    else:
        return [lst]

答案 1 :(得分:1)

如果您的列表只能包含数字或子列表(不是两者),您可以使用以下生成器功能:

In [25]: def partial_flattening(lst):
             for sub in lst:
                 if isinstance(sub[0], list):
                     yield from sub # in python 2.x use for i in sub: yeild i
                 else:          
                     yield sub
   ....:                 

In [26]: list(partial_flattening(lst))
Out[36]: [[40, 20, 45, 40], [20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]

如果可能有两种类型的组合,那么根据您想要对数字进行的操作,您可以自定义该功能。

或者作为一种更简洁的方法,您可以在列表理解中使用yield

In [29]: list([(yield from i) if isinstance(i[0], list) else (yield i) for i in lst])
Out[29]: [[40, 20, 45, 40], [20, 10, 10, 30, 45, 20], [30, 20, 20, 30]]