2016-12-15 30 views
1

好日子所有重複鍵到詞典,轉換列表中使用字典理解

我嘗試使用下面的長度爲2項的列表轉換爲一個字典:

my_list = ["b4", "c3", "c5"] 
my_dict = {key: value for (key, value) in my_list} 

的問題是當關鍵事件在列表中多於一個時,只保留最後一個關鍵字及其值。所以

在這種情況下,而不是

my_dict = {'c': '3', 'c': '5', 'b': '4'} 

我得到

my_dict = {'c': '5', 'b': '4'} 

我怎樣才能保持所有關鍵:即使有重複的鍵值對。 謝謝

+7

你會希望得到什麼'my_dict ['c']'? –

+0

for my_list中的(key,value)不應該工作 – MMF

+0

@MMF:爲什麼不呢?迭代時,'my_list'中的每個元素都有兩個值。 – DSM

回答

1

對於字典中的一個鍵,您只能存儲一個值。

您可以選擇將該值作爲列表。

{'b': ['4'], 'c': ['3', '5']} 

下面的代碼會爲你做的:

new_dict = {} 
for (key, value) in my_list: 
    if key in new_dict: 
     new_dict[key].append(value) 
    else: 
     new_dict[key] = [value] 
print(new_dict) 
# output: {'b': ['4'], 'c': ['3', '5']} 

同樣的事情可以用setdefault完成。由於@Aadit中號沙阿指出來

new_dict = {} 
for (key, value) in my_list: 
    new_dict.setdefault(key, []).append(value) 
print(new_dict) 
# output: {'b': ['4'], 'c': ['3', '5']} 

同樣的事情可以用defaultdict完成。感謝@MMF指出。

from collections import defaultdict 
new_dict = defaultdict(list) 
for (key, value) in my_list: 
    new_dict[key].append(value) 
print(new_dict) 
# output: defaultdict(<class 'list'>, {'b': ['4'], 'c': ['3', '5']}) 

你也可以選擇將值存儲爲字典列表:

[{'b': '4'}, {'c': '3'}, {'c': '5'}] 

下面的代碼會爲你做

new_list = [{key: value} for (key, value) in my_list] 
+1

與'defaultdict'你不需要檢查一個密鑰是否在字典中;) – MMF

+1

@MMF在那裏沒有分歧。 –

+1

更好的做法是'new_dict.setdefault(key,[])。append(value)'。 –

0

您可以使用defaultdict避免檢查,如果一個關鍵詞是否在詞典中:

from collections import defaultdict 

my_dict = defaultdict(list) 
for k, v in my_list: 
    my_dict[k].append(v) 

輸出:

defaultdict(list, {'b': ['4'], 'c': ['3', '5']}) 
+0

更好的是,使用常規字典來執行'my_dict.setdefault(k,[])。append(v)'。 –

0

如果你不關心O(n^2)漸近行爲,你可以使用字典理解,包括列表理解:

>>> {key: [i[1] for i in my_list if i[0] == key] for (key, value) in my_list} 
{'b': ['4'], 'c': ['3', '5']} 

iteration_utilities.groupedby函數(可能比使用更快:

>>> from iteration_utilities import groupedby 
>>> from operator import itemgetter 
>>> groupedby(my_list, key=itemgetter(0), keep=itemgetter(1)) 
{'b': ['4'], 'c': ['3', '5']}