2016-08-26 48 views
1

我有幾個字典,我想打印一個表,其中每行都是所有字典中鍵的唯一組合。對於每一行,我還想打印該特定組合中鍵值的總和。打印字典鍵的每個組合的列表以及與其相關聯的鍵值的總和

所以,如果我有這些詞典:

dict1 = {"Main": 8, "Optional": 6, "Obscure": 4} 
dict2 = {"Global": 8, "Regional": 4, "Local": 2} 
... 

輸出應該是這樣的(由總和排序最高到最低):

Main, Global, 16 
Optional, Global, 14 
Main, Regional, 12 
Obscure, Global, 12 
Main, Local, 10 
Optional, Regional, 10 
Optional, Local, 8 
Obscure, Regional, 8 
Obscure, Local, 6 

從我讀過,itertools。產品將成爲我正在尋找的東西,但是現有的問題都不是我的使用案例,我甚至都很難開始。

任何幫助,將不勝感激。

感謝

回答

1

您已閱讀權限。只需添加sorted()

from itertools import product 
from operator import itemgetter 

results = [(k1, k2, dict1[k1] + dict2[k2]) 
      for k1, k2 in product(dict1.keys(), dict2.keys())] 

for k1, k2, sum_ in sorted(results, key=itemgetter(2), reverse=True): 
    print(k1, k2, sum_, sep=', ') 
+0

這工作完美!我有很多字典,所以我不得不添加額外的變量並調整itemgetter值,但否則完美。非常感謝你:) – Brandon

1

我認爲這將是這樣的:

import itertools 

dict1 = {"Main": 8, "Optional": 6, "Obscure": 4} 
dict2 = {"Global": 8, "Regional": 4, "Local": 2} 

merged = {'{}, {}'.format(prod[0], prod[1]): dict1[prod[0]] + dict2[prod[1]] 
      for prod in itertools.product(dict1, dict2)} 

for k, v in merged.items(): 
    print('{}: {}'.format(k, v)) 

輸出:

Optional, Regional: 10 
Main, Regional: 12 
Optional, Local: 8 
Main, Global: 16 
Optional, Global: 14 
Main, Local: 10 
Obscure, Regional: 8 
Obscure, Global: 12 
Obscure, Local: 6 
1

使用productitertools詞典中的項目(),在那裏你可以得到兩個關鍵和價值,並且通過鍵值對的組合,您可以非常簡單地構建最終結果:

from itertools import product 
sorted([(k1, k2, v1+v2) for (k1, v1), (k2, v2) in product(dict1.items(), dict2.items())], \ 
     key = lambda x: x[2], reverse=True) 

# [('Main', 'Global', 16), 
# ('Optional', 'Global', 14), 
# ('Obscure', 'Global', 12), 
# ('Main', 'Regional', 12), 
# ('Main', 'Local', 10), 
# ('Optional', 'Regional', 10), 
# ('Obscure', 'Regional', 8), 
# ('Optional', 'Local', 8), 
# ('Obscure', 'Local', 6)] 
+1

這個答案是更有效率比其他發佈至今,因爲它使用'.items(避免了不必要的'dict'查找)'(雖然你應該使用'.viewitems()'在Py2上最小化臨時'list's)和不必要的'tuple'索引通過使用解包到命名變量。儘管需要添加排序步驟('key'函數的'operator.itemgetter(2)')。 – ShadowRanger

+0

@ShadowRanger雖然是真的,但它的差別很小(例如2.29μs比2.33μs,py3)。但使用'items()'和解包是一個很好的接觸。 –

1

此方法是爲支持可變數量的字典而構建的。您將字典傳遞給get_product_sums()方法,然後從字典元組創建笛卡爾積。

然後,我們重複我們的新subitem來計算總和,在我們的flattened中進行查找,現在這只是一維詞典。然後,我們按總和進行排序,然後返回我們的最終result的元組排序列表。

from itertools import product 

def get_product_sums(* args): 
    result = [] 
    flattened = {k:v for d in args for k, v in d.items()} 
    for subitem in product(* args, repeat=1): 
     data = subitem + (sum(flattened[key] for key in subitem),) 
     result.append(data) 
    return sorted(result, key=lambda x: x[-1], reverse=True) 

樣本輸出:

>>> dict1 = {"Global": 8, "Regional": 4, "Local": 2} 
>>> dict2 = {"Main": 8, "Optional": 6, "Obscure": 4} 
>>> for item in get_product_sums(dict1, dict2): 
...  print ', '.join(str(element) for element in item) 
Global, Main, 16 
Global, Optional, 14 
Global, Obscure, 12 
Regional, Main, 12 
Local, Main, 10 
Regional, Optional, 10 
Local, Optional, 8 
Regional, Obscure, 8 
Local, Obscure, 6 
+0

* args可以用來代替字典的元組 –

+0

@DiegoAllen當然!我把它作爲一個元組,因爲我不確定他處理數據的方式。 – ospahiu

相關問題