2015-11-02 104 views
3

比方說,我有以下兩個字典:重組的嵌套字典的Python

D1={'a':['a2','a3'], 'b':['b5','b7'], 'c':['c4']} 
D2={'a':2, 'b':2, 'c':5} 

我想他們重組,使D2的值是關鍵築巢D1的項目。基本上我想要下面的字典:

DictIWant={2:{'a':['a2','a3'], 'b':['b5','b7']}, 5:{'c':['c4']}} 

這樣做的最好和最有效的方法是什麼?我偶然發現了一些,並且有一種非常笨重的方式來獲得我想要的東西,但我認爲學習正確的方法是件好事。

到目前爲止,我的第一步是使用反向D2如下:

>>> from collections import defaultdict 
>>> D2_Inv = defaultdict(list) 
>>> for k, v in D2.items(): 
...  D2_Inv[v].append(k) 
... 
>>> D2_Inv=dict(D2_Inv) 
>>> D2_Inv 
{2: ['a', 'b'], 5: ['c']} 

我不是那熟悉的默認字典,但我發現瞭如何做到這一點從這樣一個問題:How to reverse a dictionary that it has repeated values (python)

然後,我一直在做以下操作:

>>> NextStep=defaultdict(list) 
>>> for Key,Value in D2_Inv.items(): 
...  for SubValue in Value: 
...   New= dict({SubValue: D1[SubValue]}) 
...   NextStep[Key].append(New) 
... 
>>> NextStep=dict(NextStep) 
>>> print NextStep 
{2: [{'a': ['a2', 'a3']}, {'b': ['b5', 'b7']}], 5: [{'c': ['c4']}]} 

也許是因爲我不熟悉defaultdict,我不知道如何讓字典的字典而不是列表的字典字典。

於是我一直在服用這最後一步,以解決這個問題:

>>> DictIWant={} 
>>> for k,v in NextStep.items(): 
...  F=v[0].copy() 
...  for i in v[1:]: 
...   F.update(i) 
...  DictIWant[k]=F 
... 
>>> print DictIWant 
{2: {'a': ['a2', 'a3'], 'b': ['b5', 'b7']}, 5: {'c': ['c4']}} 

我知道這是讓我找的結果非常笨重的方式。有人可以提供更高效/正確的解決方案嗎?

+0

'NextStep自動= defaultdict(名單)',說你的字典包含列表,但你希望你的字典包含字典,所以'NextStep自動= defaultdict(字典)',然後'NextStep自動[關鍵] .update(新)'而不是'append' – njzk2

回答

3

您可以使用collections.defaultdict(dict)來構建這個非常簡單。

from collections import defaultdict 

D1={'a':['a2','a3'], 'b':['b5','b7'], 'c':['c4']} 
D2={'a':2, 'b':2, 'c':5} 

D3 = defaultdict(dict) 

for k,v in D2.items(): 
    D3[v].update({k: D1[k]}) 

print(D3) 
# defaultdict(<class 'dict'>, {2: {'b': ['b5', 'b7'], 'a': ['a2', 'a3']}, 5: {'c': ['c4']}}) 

因爲在你的子類型的字典的每一個元素是key: D1[key](w.r.t. D2的鍵,值對),您可以使用defaultdict(dict)引用一個可能是新的字典,D3[value],然後用新元素進行更新。如果你想避免defaultdict,你也可以使用dict.setdefault

... 

D3 = {} 
for k,v in D2.items(): 
    D3.setdefault(v, {}).update({k: D1[k]}) # equivalent