Извлеките все ключи из списка словарей

Я пытаюсь получить список всех ключей в списке словарей, чтобы заполнить аргумент fieldnames для 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"]

5 Solutions collect form web for “Извлеките все ключи из списка словарей”

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

Изменить : нужно распаковать список. Теперь исправлено.

Ваши данные:

 >>> 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'} 

Он работает таким образом. Сначала создайте список списков ключей dict:

 >>> [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()} 
 >>> 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']) 

В следующем примере будут извлечены ключи:

 set_ = set() for dict_ in dictionaries: set_.update(dict_.keys()) print set_ 

Заимствование lis из ответа @ AshwiniChaudhary, вот объяснение того, как вы могли бы решить свою проблему.

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

Итерация непосредственно над dict возвращает его ключи, поэтому вам не нужно вызывать 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']) 
  • Получить или создать соответствующий ключ и пользователь (Python - движок приложения)
  • super () в Python 2.x без аргументов
  • Как установить PIL на Mac OSX 10.5.8 для Google App Engine?
  • Преобразование строки в целое с помощью map ()
  • Cython: использование импортированного класса в объявлении типа
  • Google Appengine NDB предка против ключевого запроса
  • быстро повторяя список кортежей
  • Сгенерировать все уникальные перестановки 2d массива
  • Python - лучший язык программирования в мире.