2017-07-07 80 views
1

此問題類似於帖子「Python - Convert list of single key dictionaries into a single dictionary」,其中假設是我們保證列表中的不同鍵字典。我的問題是,如果我們有相似的鍵,以及我們如何利用縮減功能會怎樣。使用減法將具有相似/重複鍵的字典列表轉換爲單個字典(值將列出)

例如,我們有:

lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]

我們希望:

dict = {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']} 

此外,後How to merge multiple dicts with same key?是相似的,除了在這裏我們想利用減少方法。

+1

爲什麼使用'reduce'?它是否必須使用「減少」? – abccd

+1

請做出一個嘗試,然後如果你卡住了,回來問問。 – wwii

+0

@wwii我真的很想知道爲什麼這個評論是可以的,而試圖評論「你試過什麼?」你會收到來自SO的消息,告訴你不能這樣做。 –

回答

1

好吧,採取的靈感來自鏈接的問題,你可以這樣做:

In [12]: from collections import defaultdict 
    ...: from functools import reduce 

In [13]: lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}] 

In [14]: def foo(r, d): 
    ...:  for k in d: 
    ...:   r[k].append(d[k]) 
    ...:   

In [16]: d = reduce(lambda r, d: foo(r, d) or r, lst, defaultdict(list)) 

In [17]: d 
Out[17]: defaultdict(list, {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']}) 

你需要一箇中間的功能做更新...我認爲有更好的方式來做到這一點,但這是關鍵所在。


現在,如果你想有一個更清潔,更可讀的方式,你可以這樣做:

In [12]: from collections import defaultdict 

In [30]: lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}] 

In [31]: d = defaultdict(list) 

In [32]: for i in lst: 
    ...:  k, v = list(i.items())[0] # an alternative to the single-iterating inner loop from the previous solution 
    ...:  d[k].append(v) 
    ...:  

In [33]: d 
Out[33]: defaultdict(list, {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']}) 
+2

..是的,不需要使用reduce。 – wwii

+1

另請注意,您必須從'collections'中導入'defaultdict()'才能使用第二種方法。 –

+0

@ChristianDean修正! –

0

我只是使用與減少方法的功能,想出了一個解決方案。

首先我們定義一個函數,用於檢查密鑰是否在dict之前插入。如果它是一個新鍵,我們將它添加到列表中的值,如果它已經存在,我們將該值附加到現有列表中。

def dict_list(each_dict): 
    d_key = each_dict.keys()[0] 
    d_value = each_dict.values()[0] 
    if d_key in return_dict: 
     return_dict[d_key].append(d_value) 
    else: 
     return_dict[d_key] = [d_value] 
    return return_dict 

然後使用此功能在單一線路降低如下:

lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}] 
return_dict = {} 
print reduce(lambda return_dict, each_dict: dict_list(each_dict), lst, {}) 
0

可以使用setdefault()屬性字典對象:

>>> def combine(dictionaries): 
    combined_dict = {} 
    for dictionary in dictionaries: 
     for key, value in dictionary.items(): 
      combined_dict.setdefault(key, []).append(value) 
    return combined_dict 

>>> 
>>> lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}] 
>>> combine(lst) 
{'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']} 
>>> 

這基本上通過首先檢查如果密鑰已經存在於新字典中。如果是這樣,我們只需將當前值附加到同一個鍵。如果沒有,我們創建一個新的密鑰並將該當前值附加到該密鑰。