2016-10-26 57 views
1

我有一個不一定具有相同鍵的字典列表。我正在嘗試創建每個包含特定鍵的字典中包含的值的新列表。Python從具有特定鍵的每個字典的字典列表創建列表

E.g.

dict1 = {'key1': 1, 'key2': 2, 'key4': 4} 
dict2 = {'key2': 2, 'key3': 3} 
dict3 = {'key1': 1, 'key2': 2, 'key3': 3} 

dict_list = [dict1, dict2, dict3] 

現在,我試圖從dict_list創建列表如下:

key2vals = [dict['key2'] for dict in dict_list] 
print(key2vals) 
    [2, 2, 2] 

行之有效,因爲「KEY2」被包含在列表中的每個詞典。但是,當我嘗試一個沒有出現在每本字典中的密鑰時,我會遇到一個錯誤。例如。 'key1':

>>> key1vals = [dict['key1'] for dict in dict_list] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <listcomp> 
KeyError: 'key1' 

有沒有一個簡短而直接的方法,我可以做下面的事情,這是行不通的?

# This does not work 
key1vals = [dict['key1'] if 'key1' in dict for dict in dict_list] 

什麼是最Python化的方法來實現這一目標?

答: 的並if語句應該已經本末倒置:

key1vals = [dict['key1'] for dict in dict_list if 'key1' in dict ] 

而且,與AbrahamB和DJV的建議,我能夠將默認值添加到這些字典沒有搜索關鍵字:

[dict.get('key1', 0) for dict in dict_list] 

回答

2
dict1 = {'key1': 1, 'key2': 2, 'key4': 4} 
dict2 = {'key2': 2, 'key3': 3} 
dict3 = {'key1': 1, 'key2': 2, 'key3': 3} 

dict_list = [dict1, dict2, dict3] 

keys = ['key1', 'key2', 'key3', 'key4', 'key5'] 
for key in keys: 
    values = [d[key] for d in dict_list if key in d] 
    print(values) 
[1, 1] 
[2, 2, 2] 
[3, 3] 
[4] 
[] 

但是相同的項目查找在這裏完成了兩次:key in dd[key]。你能避免它:

values = list(filter(None, (d.get(key) for d in dict_list))) 

values = [i for i in (d.get(key) for d in dict_list) if i is not None] 

新增: 正如你在評論中提到,你實際上需要0如果key不是在字典。只要使用get方法用默認值:

values = [d.get(key, 0) for d in dict_list] 
[1, 0, 1] 
[2, 2, 2] 
[0, 3, 3] 
[4, 0, 0] 
[0, 0, 0] 
2

絕對如此。該字典有一個「get」方法,您可以使用它。

例如

a = {} 
a.get('this-does-not-exist') 

這將返回一個無類型。現在

你可以更大膽的嘗試,比如如果沒有找到返回的默認值:

a = {} 
a.get('this-does-not-exist', []) 

它會返回一個空列表[]。

+0

您可以在原始示例問題中使用a.get('key','defaultValue')格式嗎?我並不完全遵循如何在更大的圖景中使用它。 –

+0

DJV剛剛在另一條評論中提供了答案:[d.get('key1',0)for dict_list] –

1

你是八九不離十:

key1vals = [d['key1'] for d in dict_list if 'key1' in d] 

要獲得所有鍵的值:

all_keys = {key for d in dict_list for key in d} 

result_dict = {} 
for key in all_keys: 
    result_dict[key] = [d[key] for d in dict_list if key in d] 

print(result_dict) 

它打印:

{'key1': [1, 1], 'key4': [4], 'key3': [3, 3], 'key2': [2, 2, 2]} 
0

感謝您的建議!我發現了另一個解決方案,根本扭轉了「」和「如果」在我以前嘗試聲明:

>>> key1vals = [dict['key1'] for dict in dict_list if 'key1' in dict] 
>>> key1vals 
[1, 1] 
>>> 

請問過濾器或「獲取」的方法首選呢?

+0

我會建議使用get,因爲它更乾淨。您已經在dict ['key1']中調用密鑰,所以這會比dict.get('key1') – AbrahamB

+0

更短。是的,它更短,但我認爲d'語言中的if'key1'可能會更加噁心,更易於閱讀。這種方法從字面上檢查字典是否有「key1」鍵。你不能以任何方式出錯。 – blacksite

+0

我可以在dict_list中添加一個「else」語句,如>>> key1vals = [dict ['key1'] for dict in if key1'dict else 0]。然後我想要key1vals包含[1,0,1]。 –