2012-07-09 51 views
15

我試圖獲取字典列表中所有鍵的列表,以便填寫csv.DictWriter的字段名參數。從字典列表中提取所有密鑰

以前,我有這樣的事情:

[ 
{"name": "Tom", "age": 10}, 
{"name": "Mark", "age": 5}, 
{"name": "Pam", "age": 7} 
] 

,我用fieldnames = list[0].keys()採取列表中的第一個字典,並提取其鍵。

現在我有這樣的一個字典有更多的關鍵:值對比其他人(可能是任何結果)。新密鑰是根據來自API的信息動態添加的,因此它們可能會或可能不會在每個字典中出現,並且我不會預先知道將會有多少新密鑰。

[ 
{"name": "Tom", "age": 10}, 
{"name": "Mark", "age": 5, "height":4}, 
{"name": "Pam", "age": 7} 
] 

我不能只用fieldnames = list[1].keys(),因爲它並不一定是會有額外的鑰匙的第二個元素。

一個簡單的解決辦法是找到鑰匙的數量最多的字典和使用它的字段名,但如果你有一個這樣的例子是行不通的:

[ 
{"name": "Tom", "age": 10}, 
{"name": "Mark", "age": 5, "height":4}, 
{"name": "Pam", "age": 7, "weight":90} 
] 

,其中兩個第二和第三字典有3個按鍵,但最終的結果確實應該名單["name", "age", "height", "weight"]

回答

29
all_keys = set().union(*(d.keys() for d in mylist)) 

編輯:要解包的列表中。現在修復。

+0

+1理解和優雅 – 2012-07-09 16:41:59

+0

我想這是'字段名=集()工會(運行起來也()在allresults d)'但是有一個「TypeError:不可用類型:'list'」 – orh 2012-07-09 16:45:06

+0

現在很好用,謝謝 – orh 2012-07-09 16:50:34

2

下面的例子將提取鍵:

set_ = set() 
for dict_ in dictionaries: 
    set_.update(dict_.keys()) 
print set_ 
2
>>> lis=[ 
{"name": "Tom", "age": 10}, 
{"name": "Mark", "age": 5, "height":4}, 
{"name": "Pam", "age": 7, "weight":90} 
] 
>>> {z for y in (x.keys() for x in lis) for z in y} 
set(['age', 'name', 'weight', 'height']) 
10

您的數據:

>>> LoD 
[{'age': 10, 'name': 'Tom'}, 
{'age': 5, 'name': 'Mark', 'height': 4}, 
{'age': 7, 'name': 'Pam', 'weight': 90}] 

這組解析會做到這一點:

>>> {k for d in LoD for k in d.keys()} 
{'age', 'name', 'weight', 'height'} 

它以這種方式工作。首先,創建字典鍵列表的列表:

>>> [list(d.keys()) for d in LoD] 
[['age', 'name'], ['age', 'name', 'height'], ['age', 'name', 'weight']] 

然後創建列表此列表的扁平版本:

>>> [i for s in [d.keys() for d in LoD] for i in s] 
['age', 'name', 'age', 'name', 'height', 'age', 'name', 'weight'] 

並創建一套以消除重複:

>>> set([i for s in [d.keys() for d in LoD] for i in s]) 
{'age', 'name', 'weight', 'height'} 

可以簡化爲:

{k for d in LoD for k in d.keys()} 
2

從@ AshwiniChaudhary的回答借用lis,這裏是解釋你如何解決你的問題。

>>> lis=[ 
{"name": "Tom", "age": 10}, 
{"name": "Mark", "age": 5, "height":4}, 
{"name": "Pam", "age": 7, "weight":90} 
] 

迭代直接通過字典所以你沒有打電話keys()讓他們回來,節省了函數調用,並在列表中每個元素的列表構造返回它的鍵。

>>> {k for d in lis for k in d} 
set(['age', 'name', 'weight', 'height']) 

或使用itertools.chain

>>> from itertools import chain 
>>> {k for k in chain(*lis)} 
set(['age', 'name', 'weight', 'height'])