Как создать отдельный Python dict из списка dicts путем суммирования значений с общими ключами? - PullRequest
7 голосов
/ 10 июня 2009

У меня есть список словарей, например:

dictList = [
    {'a':3, 'b':9, 'c':4},
    {'a':9, 'b':24, 'c':99},
    {'a':10, 'b':23, 'c':88}
]

Все словари имеют одинаковые ключи, например a , b , c . Я хочу создать один словарь с теми же ключами, где значения являются суммами значений с теми же ключами из всех словарей в исходном списке.

Таким образом, для приведенного выше примера результат должен быть:

{'a':22, 'b':56, 'c':191}

Что было бы наиболее эффективным способом сделать это? В настоящее время у меня есть:

result = {}
for myDict in dictList:
    for k in myDict:
        result[k] = result.setdefault(k, 0) + myDict[k]

Ответы [ 3 ]

18 голосов
/ 10 июня 2009

Если все диктовки имеют все ключи, вы можете сделать это следующим образом:

>>> dict((key, sum(d[key] for d in dictList)) for key in dictList[0])
{'a': 22, 'b': 56, 'c': 191}

[Редактировать] Если скорость является большим приоритетом, вы также можете сбрить ~ 20% (хотя и ценой некоторой читабельности) вместо следующего:

import operator, itertools
dict((key, sum(itertools.imap(operator.itemgetter(key), dictList))) 
      for key in dictList[0])

Скорость зависит от размера диктанта. Я получаю следующие значения времени для исходного списка из 3 элементов и для различных размеров (созданных путем умножения исходного списка на 10, 100 или 1000 и т. Д.):

List Size   Original      dict+generator       imap+itemgetter
      3      0.054          0.090                0.097
     30      0.473          0.255                0.236
    300      4.668          1.884                1.529
   3000     46.668         17.975               14.499

(все время для 10 000 пробежек)

Так что это немного медленнее всего на 3, но в два-три раза быстрее для больших списков.

7 голосов
/ 10 июня 2009

Попробуйте это.

from collections import defaultdict
result = defaultdict(int)
for myDict in dictList:
    for k in myDict:
        result[k] += myDict[k]
0 голосов
/ 18 октября 2012

Я не уверен, как это относится к другим ответам по скорости, но всегда есть

from collections import Counter
result = sum(map(Counter,dictList),Counter())

Counter является подклассом dict, и его можно использовать вместо dict в большинстве мест. При необходимости вы можете просто преобразовать его обратно в dict

result = dict(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...