Добавление или объединение словарей Python без потерь - PullRequest
4 голосов
/ 05 октября 2010

Я пытаюсь подсчитать IP-адреса, найденные в файле журнала на двух серверах, а затем объединить статистику словаря без потери элементов или количества. Я нашел частичное решение в другом вопросе переполнения стека, но, как вы можете видеть, он отбрасывает пару '10.10.0.1':7.

>>> a = {'192.168.1.21':23,'127.0.0.1':5,'12.12.12.12':5,'55.55.55.55':10}
>>> b = {'192.168.1.21':27,'10.10.0.1':7,'127.0.0.1':1}
>>> c = {}
>>> for elem in a:
...     c[elem] = b.get(elem, 0) + a[elem]
...
>>> print c
{'55.55.55.55': 10, '12.12.12.12': 5, '127.0.0.1': 6, '192.168.1.21': 50}

Счет добавляется вместе, но если ключ не существует в dict a, он сбрасывается. У меня возникают проблемы с выяснением последней части логики ... возможно, другой для elem в b: если a.get (elem, 0) существует: pass else добавить его в c?

Ответы [ 6 ]

5 голосов
/ 05 октября 2010

В вашем коде замените c = {} на c = b.copy()

5 голосов
/ 05 октября 2010
>>> from collections import Counter
>>> a = {'192.168.1.21':23,'127.0.0.1':5,'12.12.12.12':5,'55.55.55.55':10}
>>> b = {'192.168.1.21':27,'10.10.0.1':7,'127.0.0.1':1}
>>> Counter(a) + Counter(b)
Counter({'192.168.1.21': 50, '55.55.55.55': 10, '10.10.0.1': 7, '127.0.0.1': 6, '12.12.12.12': 5})
5 голосов
/ 05 октября 2010

Если у вас Python 2.7+, попробуйте collection.Counter

В противном случае попробуйте следующее:

a = {'192.168.1.21':23,'127.0.0.1':5,'12.12.12.12':5,'55.55.55.55':10}
b = {'192.168.1.21':27,'10.10.0.1':7,'127.0.0.1':1}
c = {}
for dictionary in (a,b):
    for k,v in dictionary.iteritems():
        c[k] = c.get(k, 0) + v
2 голосов
/ 05 октября 2010

Как насчет:

c = dict((k, a.get(k, 0) + b.get(k, 0)) for k in set(a.keys() + b.keys()))
1 голос
/ 05 октября 2010

Решение для Python 2.6 и выше:

from collections import defaultdict

def merge_count_dicts(*dicts):
    result = defaultdict(int)
    for d in dicts:
        for k, v in d.items():
            result[k] += v
    return result

def test():
    a = {'192.168.1.21':23,'127.0.0.1':5,'12.12.12.12':5,'55.55.55.55':10}
    b = {'192.168.1.21':27,'10.10.0.1':7,'127.0.0.1':1}
    c = merge_count_dicts(a, b)
    print c

if __name__ == '__main_':
    test()
1 голос
/ 05 октября 2010

Это должен быть довольно общий ответ на ваш вопрос, если я его получил.

def merge_sum_dictionaries(*dicts):
    result_dict = {}
    for d in dicts:
        for key, value in d.iteritems():
            result_dict.setdefault(key, 0)
            result_dict[key] += value
    return result_dict



if __name__ == "__main__":
    a = {'192.168.1.21':23,'127.0.0.1':5,'12.12.12.12':5,'55.55.55.55':10}
    b = {'192.168.1.21':27,'10.10.0.1':7,'127.0.0.1':1}

    print merge_sum_dictionaries(a, b)

Вывод:

{'55.55.55.55': 10, '10.10.0.1': 7, '12.12.12.12': 5, '127.0.0.1': 6, '192.168.1.21': 50}
...