Python: разделить список dicts по ключу

#python #python-3.x #list #dictionary

#python #python-3.x #Список #словарь

Вопрос:

Если у меня есть куча dicts в списке, например:

 people = [{"name": "Abe", "age": 40},
          {"name": "Bob", "age": 25},
          {"name": "Charles", "age": 32}]
 

Я хочу разделить его так, чтобы он выглядел так

 names = ["Abe", "Bob", "Charles"]
ages = [40, 25, 32]
 

Я знаю, что могу выполнить два отдельных понимания списка (например: names = [person["name"] for person in people ] дважды), но есть ли какой-нибудь трюк, чтобы разделить эти данные в однострочной строке?

Ответ №1:

Вы можете использовать zip трюк:

 >>> names, ages = zip(*(d.values() for d in people))
>>> names
('Abe', 'Bob', 'Charles')
>>> ages
(40, 25, 32)
 

Обратите внимание, что это будет работать только на Python 3.7 и более поздних версиях, поскольку в этих версиях словари упорядочены для вставки.

Ответ №2:

Вы можете использовать zip и map dict.values для списка:

 names, ages = zip(*map(dict.values, people))
 

 >>> names
('Abe', 'Bob', 'Charles')
>>> ages
(40, 25, 32)
 

Конечно, это кортежи, но это достаточно легко решить, сопоставив список с распакованным результатом:

 names, ages = map(list, zip(*map(dict.values, people)))
 

 >>> names
['Abe', 'Bob', 'Charles']
>>> ages
[40, 25, 32]
 

Ответ №3:

Предполагая, что ваши dicts имеют общую структуру (тот же набор ключей), вы можете агрегировать значения для каждого ключа с помощью:

 >>> import operator
>>> keys = people[0].keys()
>>> getter = operator.itemgetter(*keys)
>>> dict(zip(keys, zip(*map(getter, people))))
{'name': ('Abe', 'Bob', 'Charles'), 'age': (40, 25, 32)}
 

Работает в любом Python (упорядоченный dict не требуется), и это удобно для большого количества ключей / переменных.

Ответ №4:

Вы можете сделать это с помощью понимания списка, извлекая нужные имена полей из словарей:

 people = [{"name": "Abe", "age": 40},
          {"name": "Bob", "age": 25},
          {"name": "Charles", "age": 32}]

names,ages = ([p[field] for p in people] for field in ("name","age"))

print(names)  # ['Abe', 'Bob', 'Charles']

print(ages)   # [40, 25, 32]