2013-10-03 159 views
0

我有一個列表,其中包含一定數量的詞典,其中我必須與其他詞典進行比較。將詞典列表與另一個詞典結合起來

他們有以下形式(沒有具體的形式或圖案的鍵和值,這是隨機選取的例子):

list1 = [ 
    {'X1': 'Q587', 'X2': 'Q67G7', ...}, 
    {'AB1': 'P5K7', 'CB2': 'P678', ...}, 
    {'B1': 'P6H78', 'C2': 'BAA5', ...}] 

dict1 = { 
    'X1': set([B00001,B00020,B00010]), 
    'AB1': set([B00001,B00007,B00003]), 
    'C2': set([B00001,B00002,B00003]), ... 
} 

我想現在已經是其具有作爲密鑰的新字典:list1中的字典的值。並作爲值dict1的值。只有當鑰匙在比較詞典中相交時。

nDicts = len(list1) 
resultDict = {} 

    for key in range(0,nDicts): 
      for x in list1[key].keys(): 
       if x in dict1.keys(): 
        resultDict.update{list1[key][x]:dict1[x]} 
        print resultDict 

所需的輸出應該是這樣的形式:

我在下面的方式做到了這一點

resulDict = { 
     'Q587': set([B00001,B00020,B00010]), 
     'P5K7': set([B00001,B00007,B00003]), 
     'BAA5': set([B00001,B00002,B00003]), ... 
    } 

這工作,但由於數據量是如此之高,這需要永遠。 有沒有更好的方法來做到這一點?

編輯:我改變了一點輸入值,唯一重要的是在list1和dict1內的字典之間相交的鍵。

+0

哪一個更大? 'list1'或'dict1'? – Hyperboreus

+1

有沒有出現在'list1'中的多個字典中的鍵? – Hyperboreus

+0

您能否請您展示一些實際的樣本數據(可以評估和使用,而不是語法錯誤)以及所需的輸出數據? – abarnert

回答

1

Python 2.x中的keys方法列出了所有按鍵的副本,而且您不僅爲每個字典在list1(可能不是什麼大不了的,但很難知道的當然不知道你的數據),但也一遍又一遍地爲dict1做。

最重要的是,對列表執行in測試需要很長時間,因爲它必須檢查列表中的每個值直到找到匹配,但是對字典進行in測試幾乎是即時的,因爲它只需查找散列值。

兩個keys實際上是完全沒有必要的,迭代的字典爲您提供了順序按鍵(未指定的順序,但相同的是真正的調用keys()),並in - 檢查的字典搜索你會與得到相同的密鑰keys()。所以,只是刪除它們會做同樣的事情,但更簡單,更快速,並且使用更少的內存。所以:

for key in range(0,nDicts): 
    for x in list1[key]: 
     if x in dict1: 
      resultDict={list1[key][x]:dict1[x]} 
      print resultDict 

也有方法可以簡化這一點,可能不會幫助性能多,但仍值得做的事情。

您可以直接在list1上迭代,而不是構建所有索引的巨大列表並對其進行迭代。

for list1_dict in list1: 
    for x in list1_dict: 
     if x in dict1: 
      resultDict = {list_dict[x]: dict1[x]} 
      print resultDict 

而且你可以在一個單一的步驟鍵和值:約兩倍長

for list1_dict in list1: 
    for k, v in list1_dict.iteritems(): 
     if k in dict1: 
      resultDict = {v: dict1[k]} 
      print resultDict 

另外,如果您希望大部分值被發現,它會先檢查爲價值,然後查看它,因爲它會試圖查找它並處理失敗。 (但是,如果找到大多數值而不是,則不是這樣。)所以:

for list1_dict in list1: 
    for k, v in list1_dict.iteritems(): 
     try: 
      resultDict = {v: dict1[k]} 
      print resultDict 
     except KeyError: 
      pass 
+1

「迭代字典給你的順序鍵」。哪個訂單? – Hyperboreus

+0

這就是OP的代碼樣本,但更好。但是他的問題似乎並沒有提出要求,這是創建一個單一的字典。 –

+0

@Hyperboreus:一個未指定的順序,但與key()會給你的順序相同 - 在這種情況下無關緊要。我已經編輯它來澄清這一點。 – abarnert

1

您可以通過設置交點來簡化和優化您的操作;像Python 2.7字典可以在Python 3代表鍵爲使用dict.viewkeys()方法設置,或dict.keys()

resultDict = {} 

for d in list1: 
    for sharedkey in d.viewkeys() & dict1: 
     resultDict[d[sharedkey]] = dict1[sharedkey] 

這可以變成一個字典理解甚至:

resultDict = {d[sharedkey]: dict1[sharedkey] 
       for d in list1 for sharedkey in d.viewkeys() & dict1} 

我在這裏假設你想要一個結果字典,而不是每個共享密鑰的新字典。

演示你的樣品輸入:

>>> list1 = [ 
...  {'X1': 'AAA1', 'X2': 'BAA5'}, 
...  {'AB1': 'AAA1', 'CB2': 'BAA5'}, 
...  {'B1': 'AAA1', 'C2': 'BAA5'}, 
... ] 
>>> dict1 = { 
...  'X1': set(['B00001', 'B00002', 'B00003']), 
...  'AB1': set(['B00001', 'B00002', 'B00003']), 
... } 
>>> {d[sharedkey]: dict1[sharedkey] 
... for d in list1 for sharedkey in d.viewkeys() & dict1} 
{'AAA1': set(['B00001', 'B00002', 'B00003'])} 

注意兩個X1AB1與字典中list1共享,但在這兩種情況下,所產生的關鍵是AAA1。只有其中一場勝利(最後一場比賽),但是因爲dict1中的兩個值都完全相同,所以在這種情況下不會有任何可能性。

如果您在list1想每字典單獨的字典,只需要移動for d in list1:環出:

for d in list1: 
    resultDict = {d[sharedkey]: dict1[sharedkey] for sharedkey in d.viewkeys() & dict1} 
    if resultDict: # can be empty 
     print resultDict 

如果你真的想每個共享密鑰一個詞典,移動另一個環出:

for d in list1: 
    for sharedkey in d.viewkeys() & dict1: 
     resultDict = {d[sharedkey]: dict1[sharedkey]} 
     print resultDict 
0
#!/usr/bin/env python 

list1 = [ 

    {'X1': 'AAA1', 'X2': 'BAA5'}, 
    {'AB1': 'AAA1', 'CB2': 'BAA5'}, 
    {'B1': 'AAA1', 'C2': 'BAA5'} 

    ] 


dict1 = { 
    'X1': set(['B00001','B00002','B00003']), 
    'AB1': set(['B00001','B00002','B00003']) 
}  


g = (k.iteritems() for k in list1) 
ite = ((a,b) for i in g for a,b in i if dict1.has_key(a)) 

d = dict(ite)    
print d