2017-10-04 42 views
2

我有這樣的表結構:使用Python連接列出的名單列表鍵

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 

「善堂」可以包含子列表任意數量(LEN(LST)可以大於2)

作爲輸出我想:

output = [['a',100,50],['b',200,250],['c',0,75],['d',325,0]] 

下面是另一個例子:

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]]] 

output = [['a', 100, 50, 22],['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 

你會怎麼做?

+0

爲什麼有些項目應該包含零像'['c',0,75]'? – RomanPerekhrest

+0

'lst'總是會有這樣的結構嗎? IOW,它會一直是(列表(兩個項目列表))列表嗎? –

+0

@RomanPerekhrest它會出現,因爲第一個子列表不包含'c'「鍵」,所以OP希望它默認爲0 – Wondercricket

回答

2

這個任務會有點簡單,如果我們在lst使用的所有字母鍵的列表,但它很容易足以提取它們。

我的策略是將子列表轉換爲字典。這使得高效地獲取與每個密鑰相關聯的值。 dict.get方法允許我們提供缺失鍵的默認值。

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 

# Convert outer sublists to dictionaries 
dicts = [*map(dict, lst)] 

# Get all the keys 
keys = set() 
for d in dicts: 
    keys.update(d.keys()) 

# Get data for each key from each dict, using 0 if a key is missing 
final = [[k] + [d.get(k, 0) for d in dicts] for k in sorted(keys)] 
print(final) 

輸出

[['a', 100, 50], ['b', 200, 250], ['c', 0, 75], ['d', 325, 0]] 

如果我們使用

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]]] 

然後輸出

[['a', 100, 50, 22], ['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 

如果您想在Python 2上運行此功能,則需要對將外部子列表轉換爲字典的代碼進行小的更改。將其更改爲

dicts = list(map(dict, lst)) 

這將正常工作,雙方的Python 2 & 3.如果你只需要在Python 2中運行它,你可以簡單地做

dicts = map(dict, lst) 

因爲map在Python 2回報一個列表,而不是一個迭代器。

+0

好的答案,但可能會提到這是一個Python 3.5 <解決方案。 OP沒有明確說明他們使用的是哪個版本 – Wondercricket

+0

@Wondercricket SO Python社區策略是承擔Python 3,除非明確聲明Python 2。 ;)但是我會在我的答案中添加一些相關信息。 –

+0

我不知道這個政策,這是很好的知道:) – Wondercricket

2

您可以使用defaultdict

from collections import defaultdict 
import itertools 
d = defaultdict(list) 
lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 
for a, b in itertools.chain.from_iterable(lst): 
    d[a].append(b) 

new_lst = sorted([list(itertools.chain.from_iterable([[a], [0 for i in range(len(max(d.items(), key=lambda x:len(x[-1])))-len(b))]+b])) for a, b in d.items()]) 

輸出:

[['a', 100, 50], ['b', 200, 250], ['c', 0, 75], ['d', 0, 325]] 
+0

thx @ Ajax1234您的解決方案可以很好地處理兩個子列表,但有兩個以上的子列表,如[[['a',100],['b',200],['d',325]], [['a',50],['b',250],['c',75]],[['a',22],['b':10]]]我得到了輸出: ['a',100,50,22],['b',200,250,10],['c',0,75],['d',0,325]]應該是[[' a',100,50,22],['b',200,250,10],['c',0,75,0],['d',325,0,0]] – gimba

2

隨着itertools.chain.from_iterable()itertools.groupby()功能和內置next()功能:

import itertools 

lst = [ [['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]] ] 
lst_len = len(lst) 
sub_keys = [{k[0] for k in _} for _ in lst] 
result = [[k] + [next(g)[1] if k in sub_keys[i] else 0 for i in range(lst_len)] 
      for k,g in itertools.groupby(sorted(itertools.chain.from_iterable(lst), key=lambda x:x[0]), key=lambda x: x[0])] 

print(result) 

輸出:

[['a', 100, 50, 22], ['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 
+0

@ PM2Ring,爲更大的列表添加設置 – RomanPerekhrest

0

這是我的 「長手」 的方法,我不得不制定出什麼正在進行:

lst = [[['a', 100],['b', 200],['d', 325]], 
     [['a', 50],['b', 250],['c', 75]], 
     [['a', 22], ['b', 10]], 
     [['c', 110],['f', 200],['g', 425]], 
     [['a', 50],['f', 250],['h', 75]], 
     [['a', 32], ['b', 10]], ] 
nlist = [] 
store={} 
for n,j in enumerate(lst): 
    for i in j : 
     if i[0] in store : 
      store[i[0]].append(i[1]) 
     else : 
      store[i[0]] = nlist + [i[1]] 
    nlist += [0] 
    for k,v in store.items() : 
     if len(v) < n+1 : 
      store[k] = v + [0] 
print(store) 
result=[] 
for k,v in store.items(): 
    result += [[k] + v] 
print(sorted(result))