2013-11-24 52 views
1

我想兩個庫相結合,以產生這樣的結果:字典中合併詞典及增加值

a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2} 
b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5} 
ab = {"cat": 5, "dog": 4, "rabbit": 20, "horse": 8, "shoe": 2, "fish": 9} 

所以,如果他們有相同的鍵,值將被添加,如果一個關鍵是出現在一個詞典中而不是另一個詞典中,它會將其添加到具有相應值的新詞典中。

這兩個字典也都嵌套在單獨的字典,以及使得:

x = {'a': {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2}, 'c': blah, 'e': fart} 
y = {'a': {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5}, 'c': help, 'e': me} 

鍵是在兩個主字典相同的。

我一直在試圖將兩個庫合併:

def newdict(x,y): 
    merged= [x,y] 
    newdict = {} 
    for i in merged: 
     for k,v in i.items(): 
      new.setdefault(k,[]).append(v) 

這一切使我是屬於列表中的相同的密鑰值的字典。我無法弄清楚如何遍歷一個鍵的兩個列表並將這些值一起添加來創建一個聯合字典。誰能幫我?

最終結果應該是這樣的:

xy = {'a' = {"cat": 5, "dog": 4, "rabbit": 20, "horse": 8, "shoe": 2, "fish": 9}, 'c': blah, 'e': me} 

的「c」和「E」鍵我將必須遍歷並執行基於從「A」的結果的不同的計算。

我希望我能夠清楚地解釋我的問題。

回答

1

要做到這一點很容易,你可以使用collections.Counter

>>> from collections import Counter 
>>> a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2} 
>>> b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5} 
>>> Counter(a) + Counter(b) 
Counter({'rabbit': 20, 'fish': 9, 'horse': 8, 'cat': 5, 'dog': 4, 'shoe': 2}) 

所以,你的情況,這將是這樣的:

newdict['a'] = Counter(x['a']) + Counter(y['a']) 

如果您由於某種原因不希望它成爲計數器,您只需將結果傳遞給dict()即可。


編輯:

如果你不允許進口的,你必須手工做加法,但是這應該足夠簡單。
因爲這聽起來像功課,我給你一些提示,而不是一個完整的答案:

  • 創建所有鍵的集合,或循環每個字典(你可以用一組,以確保鍵是唯一的,但重複不應該是一個問題,因爲他們會被覆蓋)
  • 每個鍵,在舊類型的字典中添加值的總和爲新字典(可以使用dict.get()得到一個0,如果鑰匙不存在)
+0

感謝您的快速回復,但是我不允許導入任何函數,所以我一直在試圖找到一種方法來編寫代碼來手動實現計數。有任何想法嗎? – user3027711

+0

我已經添加了一些提示,可以幫助您自行解決問題。 – stranac

1

使用collections.Counterisinstance

>>> from collections import Counter 
>>> from itertools import chain 
>>> x = {'e': 'fart', 'a': {'dog': 4, 'rabbit': 19, 'shoe': 2, 'cat': 3, 'horse': 3}, 'c': 'blah'} 
>>> y = {'e': 'me', 'a': {'rabbit': 1, 'fish': 9, 'cat': 2, 'horse': 5}, 'c': 'help'} 
>>> c = {} 
>>> for k, v in chain(x.items(), y.items()): 
    if isinstance(v, dict): 
     c[k] = c.get(k, Counter()) + Counter(v) 
...   
>>> c 
{'a': Counter({'rabbit': 20, 'fish': 9, 'horse': 8, 'cat': 5, 'dog': 4, 'shoe': 2})} 

現在的基礎上'a'的價值,你可以計算出密鑰'a''e'值,但這次使用:if not isinstance(v, dict)

更新:解決方案不使用進口:

>>> c = {} 
>>> for d in (x, y): 
    for k, v in d.items(): 
     if isinstance(v, dict): 
      keys = (set(c[k]) if k in c else set()).union(set(v)) #Common keys 
      c[k] = { k1: v.get(k1, 0) + c.get(k, {}).get(k1, 0) for k1 in keys} 
...    
>>> c 
{'a': {'dog': 4, 'rabbit': 20, 'shoe': 2, 'fish': 9, 'horse': 8, 'cat': 5}} 
+0

不幸的是,我不允許導入任何功能。有沒有辦法進行計算而不導入?感謝您的幫助。 – user3027711

+0

@ user3027711我已經添加了另一種解決方案。 –

1

我的嘗試將是:

a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2} 
b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5} 
def newdict(x, y): 
    ret = {} 
    for key in x.keys(): 
     if isinstance(x[key], dict): 
      ret[key] = newdict(x[key], y.get(key, {})) 
      continue 
     ret[key] = x[key] + y.get(key, 0) 
    for key in y.keys(): 
     if isinstance(y[key], dict): 
      ret[key] = newdict(y[key], x.get(key, {})) 
      continue 
     ret[key] = y[key] + x.get(key, 0) 
    return ret 
ab = newdict(a, b) 
print ab 
> {'horse': 8, 'fish': 9, 'dog': 4, 'cat': 5, 'shoe': 2, 'rabbit': 20} 

說明:

newdict函數首先遍歷第一個字典(x)。對於x中的每個鍵,它將在新詞典中創建一個新條目,將該值設置爲總和x[key]y[key]dict.get函數提供可選的第二個參數,它在key不在dict中時返回。

如果x[key]是一個字典,它設置ret[key]x[key]y[key]合併字典。

然後對y做相同的處理並返回。

注:這並不適用於功能工作。嘗試在那裏找出自己的東西。

0
def newDict(a,b): 
    newD={} 
    for key in a: 
    newD[key]=a[key] 
    for key in b: 
    newD[key]=newD.get(key,0)+b[key] 
    return newD