0

我想寫一個字典理解。協助與詞典理解

我有這樣一個字典:

main_dict = { 
    'A' : {'key1' : 'valueA1', 'key2' : 'valueA2'}, 
    'B' : {'key2' : 'valueB2', 'key3' : 'valueB3'}, 
    'C' : {'key3' : 'valueC3', 'key1' : 'valueC1'}} 

我想執行以下邏輯:

d = {} 
for k_outer, v_outer in main_dict.items(): 
    for k_inner, v_inner in v_outer.items(): 
     if k_inner in d.keys(): 
      d[k_inner].append([k_outer, v_inner]) 
     else: 
      d[k_inner] = [[k_outer, v_inner]] 

其產生以下結果:

{'key3': [['C', 'valueC3'], ['B', 'valueB3']], 
'key2': [['A', 'valueA2'], ['B', 'valueB2']], 
'key1': [['A', 'valueA1'], ['C', 'valueC1']]} 

(我知道我可以使用defaultdict(list)但這只是一個例子)

我想用一個字典,理解到執行邏輯,所以到目前爲止,我有以下幾點:

d = {k : [m, v] for m, x in main_dict.items() for k, v in x.items()} 

這是不行的,它只是給了我下面的輸出:

{'key3' : ['B', 'valueB3'], 
'key2' : ['B', 'valueB2'], 
'key1' : ['C', 'valueC1']} 

哪是爲每個inner_key找到的最後一個實例...

我迷失如何正確執行這種嵌套的列表理解。我嘗試了多種變化,比最後一次更糟糕。

+3

爲清楚起見,你能告訴我們你希望你的例子輸入輸出? –

+1

你確定把所有這些邏輯都用在詞典理解中是個好主意嗎?有時可讀性比幾行代碼更好。 – pemistahl

+1

@PeterStahl很顯然你以前沒有 –

回答

0

,這是我使用的:

from collections import defaultdict 

d = defaultdict(list) 
for m, x in main_dict.items(): 
    for k, v in x.items(): 
     d[k].append((m, v)) 
2

你可以嘗試這樣的事情:

In [61]: main_dict 
Out[61]: 
{'A': {'key1': 'valueA1', 'key2': 'valueA2'}, 
'B': {'key2': 'valueB2', 'key3': 'valueB3'}, 
'C': {'key1': 'valueC1', 'key3': 'valueC3'}} 

In [62]: keys=set(chain(*[x for x in main_dict.values()])) 

In [64]: keys 
Out[64]: set(['key3', 'key2', 'key1']) 

In [63]: {x:[[y,main_dict[y][x]] for y in main_dict if x in main_dict[y]] for x in keys} 
Out[63]: 
{'key1': [['A', 'valueA1'], ['C', 'valueC1']], 
'key2': [['A', 'valueA2'], ['B', 'valueB2']], 
'key3': [['C', 'valueC3'], ['B', 'valueB3']]} 

更可讀的解決方案使用dict.setdefault

In [81]: d={} 

In [82]: for x in keys: 
    for y in main_dict: 
     if x in main_dict[y]: 
      d.setdefault(x,[]).append([y,main_dict[y][x]]) 
    ....:    

In [83]: d 
Out[83]: 
{'key1': [['A', 'valueA1'], ['C', 'valueC1']], 
'key2': [['A', 'valueA2'], ['B', 'valueB2']], 
'key3': [['C', 'valueC3'], ['B', 'valueB3']]} 
+2

換句話說,把它留作循環。 –

+0

這是一個有趣的想法 - 首先提取密鑰,它可以全部在一行中完成,但它仍然意味着通過兩次'main_dict'鍵迭代。而我上面發佈的'長'方法一次完成整個事情。我確信有一種方法可以有效地使用字典理解和一次傳遞,只需要找到它。 –

1

採用三名字典解析來實現這樣的任務,第三字典,理解是要結合前兩個字符:

e = {k : [m, v] for m, x in main_dict.items() for k, v in x.items()} 
f = {k : [m, v] for m, x in main_dict.items() for k, v in x.items() if [m,v] not in e.values()} 
g = {k1 : [m, v] for k1,m in e.items() for k2,v in f.items() if k1==k2} 
+1

當然,如果你真的想讓任何人都不可能再讀一遍,你就可以將這整個事物合併成一個巨大的嵌套理解。 :) – abarnert

+0

我寫這個只是爲了展示pythonic方式和字典理解的微妙之處。 – mayaa

+0

我發佈的樣本詞典僅僅是一個示例/實例,真正的詞典有更多的條目,這種解決方案不會工作 - 如果它被改編(即每個條目更多的詞典),這將是非常低效的。 –

0

One opti在是利用itertools.groupby

from itertools import groupby 
from operator import itemgetter 

main_dict = { 
    'A' : {'key1' : 'valueA1', 'key2' : 'valueA2'}, 
    'B' : {'key2' : 'valueB2', 'key3' : 'valueB3'}, 
    'C' : {'key3' : 'valueC3', 'key1' : 'valueC1'}} 

## Pull inner key, outer key and value and sort by key (prior to grouping) 
x = sorted([(k2, [k1, v2]) for k1, v1 in main_dict.items() for k2, v2, in v1.items()]) 

## Group by key. This creates an itertools.groupby object that can be iterated 
## to get key and value iterables 
xx = groupby(x, key=itemgetter(0)) 

for k, g in xx: 
    print('{0} : {1}'.format(k, [r[1] for r in list(g)])) 

根據您的數據和性能要求,整理可能不理想所以它的價值分析。

此外,它不會導致指定的字典,而是一個groupby對象。這可能是「類似於字典」的,足以滿足您的需求;迭代它會產生關鍵和迭代。

到底
+0

但是我怎樣才能像字典一樣使用這個數據結構呢? –

+0

通過迭代的方式如圖所示,並根據需要使用鍵和值列表,或迭代它並將其放入字典中。如果你真的需要字典,也許這不是一個合適的解決方案。 –