2011-10-14 50 views
1

標題可能會產生誤導,因此在出現真正問題的術語時可隨意更改措辭。 =)共享共同項目的合併/附加列表

在這種情況下,我知道這些列表大部分可能與元組互換。就我而言,最終的結果可以是任何可迭代的。

我有兩個列表清單。假設它們是:

list_a = [[1, 'f00d'], [2, 'dead'], [3, 'beef']] 
list_b = [[1, 'frankenbeans'], [2, 'chickensoup'], [3, 'spaceballs']] 

既不列表是一定相同的長度,也沒有得到保證爲它們含有一個共同的第一個元素。

我想要做的就是創建一個新的列表中,列表/列表的元組/列表的-類型的字典/不管,因爲這樣的:

list_c = [[1, 'f00d', 'frankenbeans'], [2, 'dead', 'chickensoup'], [3, 'beef', 'spaceballs'] 

更新: 基本上,我知道這些列表中的公共「ID」的位置,但它不一定是連續的,也不是相同順序的列表列表(但是是整數)。我正在尋找一種有效的方式來基於該公共ID創建一組新的子列表。

用簡單的方式:

new_list = [] 
for list_a_list in list_a: 
    for list_b_list in list_b: 
    if list_a_list[0] = list_b_list[0]: 
     new_list.append([list_a_list[0], list_a_list[1], list_b_list[1]]) 

...或一些這樣的。給我感覺有一個「更聰明」的方式來做到這一點,但我有點吮吸。

更新:
不會添加任何影響,如果我提到,每個列表中,列出了在同一時間進行數千至一萬件?

回答

0
from collections import defaultdict 
from itertools import chain 

final = defaultdict(list) 

for idx, value in chain(l1, l2): 
    final[idx].append(value) 

# and if you have to have a list of lists at the end 
finalList = [[k] + v for k, v in final.iteritems()] 
0

您的輸入列表應該是擺在首位的字典:

dict_a = dict(list_a) 
dict_b = dict(list_b) 
dict_c = dict((k, [v, dict_b[k]]) for k,v in dict_a.items()) 

如果鑰匙不能保證兩個列表中出現,你就必須要更加仔細:

all_keys = set(dict_a.keys()) | set(dict_b.keys()) 
dict_c = dict((k, (dict_a.get(k), dict_b.get(k))) for k in all_keys) 

例如,對於list_a = [(1, 'a')]list_b = [(1, 'b'), (2, 'c')],上述設置將dict_c設置爲{1: ('a', 'b'), 2: (None, 'c')}

+0

這可能會引發KeyError。 >>這兩個列表都不一定是相同的長度,也不保證它們包含共同的第一個元素。 –

+0

@ g.d.d.c好點。如果不存在,則添加一個版本,將元組中的元素設置爲「None」。當然,在這些情況下,也可以只構造一個元素的列表或元組。 – phihag

0

itertools.groupby()是這樣的任務有所幫助:

from itertools import groupby, chain 
from operator import itemgetter 

list_a = [[1, 'f00d'], [2, 'dead'], [3, 'beef']] 
list_b = [[1, 'frankenbeans'], [2, 'chickensoup'], [3, 'spaceballs']] 

combined = [(k, [v[1] for v in g]) for k, g in 
      groupby(sorted(list_a+list_b), key=itemgetter(0))] 

print combined 

注意,有必要建立一個新的排序列表結合list_a和list_b之前,我們可以使用GROUPBY,因爲GROUPBY假定名單將已經按鍵排序。