添加或合并Python字典而不丢失内容

4
我正在尝试计算两个服务器的日志文件中发现的IP地址,并将字典统计数据合并在一起,同时不会丢失元素或计数。我在另一个stackoverflow问题中找到了部分解决方案,但正如您所看到的,它删除了'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}

计数正在相加,但如果字典a中不存在该键,则会被丢弃。我在解决最后一部分逻辑时遇到了麻烦...也许可以再添加一个for elem in b: 如果a.get(elem, 0)存在:则跳过,否则将其添加到c中?
6个回答

5
如果您拥有Python 2.7+,请尝试使用collections.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

我正在使用Redhat Enterprise Server 4服务器,因此我有Python 2.3.4。 - user221014

5
>>> 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})

是的,你所需要的就是 Counter(a) + Counter(b) - k107

5

在你的代码中,将 c = {} 替换为 c = b.copy()


2
如何:
c = dict((k, a.get(k, 0) + b.get(k, 0)) for k in set(a.keys() + b.keys()))

1

如果我理解正确,这应该是一个相当通用的答案。

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}

1

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()

那是另一种设置 setdefault() 的方式 :P - Alan Franzoni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接