简体   繁体   English

部分列表Python拼合

[英]Partial list Flattening in Python

I have a small problem where I lack quite some Python experience. 我有一个小问题,我缺乏一些Python经验。 Assuming a list: 假设清单:

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

I want to do something I call 'partial flattening' because the expected output is: 我想做一些我称为“部分展平”的事情,因为预期的输出是:

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

Notice before the lentgh of list was 2 while the expected output has length of 3 . 注意list的lentgh是2而预期输出的长度是3 The problem is that I don't know in advance which element from list is nested one layer deeper. 问题是我事先不知道list哪个元素嵌套了更深一层。

This answer and many others didn't help much, because the flattening goes to far. 这个答案和许多其他问题并没有太大帮助,因为扁平化发展得很远。 Following the question the output is: 在问题之后的输出是:

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

(notice the missing brackets for the first 4 elements from the list. (请注意列表中前4个元素的缺失括号。

You can create a recursive function, testing whether all the inner elements are lists. 您可以创建一个递归函数,测试是否all内部元素都是列表。 If so, recursively apply the algorithm, otherwise yield the list itself. 如果是这样,则递归地应用算法,否则产生列表本身。

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

Or using yield from (Python 3.3 and later): 或使用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

Or without generators: 或没有发电机:

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]

If your lists can only contains numbers or sub lists (not both of them) you can use following generator function: 如果列表只能包含数字或子列表(不能同时包含两者),则可以使用以下生成器功能:

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

If there may be combination of both types then based on what you want to do with the numbers you can customize the function. 如果两种类型都可能组合在一起,则可以根据您要对数字进行的操作来自定义功能。

Or as a more concise approach you can use yield within list comprehension: 或者,作为更简洁的方法,您可以在列表推导中使用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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM