2017-08-04 40 views
0

我有一個小問題,我缺乏一些Python體驗。 假設列表:部分列表在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的lentgh是2而預期輸出有長度3。問題是我不知道list中的哪個元素嵌套了更深一層。

This answer和許多其他人沒有什麼幫助,因爲扁平化程度很高。以下問題的輸出是:

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

(注意缺少的括號從列表中的第4個元素

+2

所以,你希望所有的最裏面列出的名單?是否有像[1,2,[3,4]]這樣的輸入列表,如果是,那該如何平鋪? –

+0

@tobias_k像這樣的輸入列表是不可能的。 – skrat

+1

你告訴我們這個具體例子的輸出是什麼,我明白這一點。但是這個決定是基於什麼?什麼應該扁平化的規則是什麼?完全不清楚邏輯應該是什麼樣子?一旦你在那裏,考慮到你已經看到並使用了其他扁平化方法,你自己解決了什麼問題? – poke

回答

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

在Python 3中,你可以使用'yield from inner_lists(inner)' –

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

不知道你可以在列表comp中使用yield。但是,兩者都只適用於單層嵌套(在OP的例子中這可能完全沒問題) –