结合词典中的词典和添加值

时间:2013-11-24 17:37:52

标签: python python-3.x dictionary

我正在尝试合并两个词典来产生这样的结果:

a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2}
b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5}
ab = {"cat": 5, "dog": 4, "rabbit": 20, "horse": 8, "shoe": 2, "fish": 9}

因此,如果它们具有相同的键,则将添加值,如果一个字典中存在一个键但不存在另一个字典,则会将其添加到具有相应值的新字典中。

这两个词典也嵌套在单独的词典中,以便:

x = {'a': {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2}, 'c': blah, 'e': fart}
y = {'a': {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5}, 'c': help, 'e': me}

两个主要词典中的键都相同。

我一直试图将两个词典结合起来:

def newdict(x,y):
    merged= [x,y]
    newdict = {}
    for i in merged:
        for k,v in i.items():
            new.setdefault(k,[]).append(v)

所有这些给了我一个字典,其中的值属于列表中的相同键。我无法弄清楚如何迭代密钥的两个列表并将值一起添加以创建一个联合字典。任何人都可以帮助我吗?

最终结果应该是:

xy = {'a' = {"cat": 5, "dog": 4, "rabbit": 20, "horse": 8, "shoe": 2, "fish": 9}, 'c': blah, 'e': me}

'c'和'e'键我将不得不迭代并根据'a'的结果执行不同的计算。

我希望我能够清楚地解释我的问题。

5 个答案:

答案 0 :(得分:1)

要轻松完成,您可以使用collections.Counter

>>> from collections import Counter
>>> a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2}
>>> b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5}
>>> Counter(a) + Counter(b)
Counter({'rabbit': 20, 'fish': 9, 'horse': 8, 'cat': 5, 'dog': 4, 'shoe': 2})

所以,在你的情况下,它会是这样的:

newdict['a'] = Counter(x['a']) + Counter(y['a'])

如果由于某种原因不希望它成为计数器,您只需将结果传递给dict()


编辑:

如果您不允许进口,则必须手动添加,但这应该足够简单 因为这听起来像家庭作业,我会给你一些提示,而不是一个完整的答案:

  • 创建所有键的集合,或循环遍历每个dict(您可以使用一组来确保键是唯一的,但重复不应该是一个问题,因为它们将被覆盖)
  • 对于每个密钥,将旧的dicts中的值的总和添加到新的dict中(如果密钥不存在,可以使用dict.get()获取0)

答案 1 :(得分:1)

使用collections.Counterisinstance

>>> from collections import Counter
>>> from itertools import chain
>>> x = {'e': 'fart', 'a': {'dog': 4, 'rabbit': 19, 'shoe': 2, 'cat': 3, 'horse': 3}, 'c': 'blah'}
>>> y = {'e': 'me', 'a': {'rabbit': 1, 'fish': 9, 'cat': 2, 'horse': 5}, 'c': 'help'}
>>> c = {}
>>> for k, v in chain(x.items(), y.items()):
    if isinstance(v, dict):
        c[k] = c.get(k, Counter()) + Counter(v)
...         
>>> c
{'a': Counter({'rabbit': 20, 'fish': 9, 'horse': 8, 'cat': 5, 'dog': 4, 'shoe': 2})}

现在根据'a'的值,您可以计算键'a''e'的值,但这次使用:if not isinstance(v, dict)

更新:不使用导入的解决方案:

>>> c = {}
>>> for d in (x, y):
    for k, v in d.items():
        if isinstance(v, dict):
            keys = (set(c[k]) if k in c else set()).union(set(v)) #Common keys
            c[k] = { k1: v.get(k1, 0) + c.get(k, {}).get(k1, 0) for k1 in keys}
...             
>>> c
{'a': {'dog': 4, 'rabbit': 20, 'shoe': 2, 'fish': 9, 'horse': 8, 'cat': 5}}

答案 2 :(得分:1)

我的尝试是:

a = {"cat": 3, "dog": 4, "rabbit": 19, "horse": 3, "shoe": 2}
b = {"cat": 2, "rabbit": 1, "fish": 9, "horse": 5}
def newdict(x, y):
    ret = {}
    for key in x.keys():
        if isinstance(x[key], dict):
            ret[key] = newdict(x[key], y.get(key, {}))
            continue
        ret[key] = x[key] + y.get(key, 0)
    for key in y.keys():
        if isinstance(y[key], dict):
            ret[key] = newdict(y[key], x.get(key, {}))
            continue
        ret[key] = y[key] + x.get(key, 0)
    return ret
ab = newdict(a, b)
print ab
> {'horse': 8, 'fish': 9, 'dog': 4, 'cat': 5, 'shoe': 2, 'rabbit': 20}

说明:

newdict函数首先遍历第一个字典(x)。对于x中的每个键,它会在新词典中创建一个新条目,将值设置为x[key]y[key]的总和。 dict.get函数提供了一个可选的第二个参数,当key不在dict时,它会返回。

如果x[key]是dict,则会将ret[key]设置为x[key]y[key]的合并字典。

然后对y执行相同操作并返回。

注意:这不适用于功能。尝试在那里找出一些东西。

答案 3 :(得分:0)

def newDict(a,b):
  newD={}
  for key in a:
    newD[key]=a[key]
  for key in b:
    newD[key]=newD.get(key,0)+b[key]
  return newD

答案 4 :(得分:0)

我天真的解决方案是:

a = {'a':'b'}
b = {'c':'d'}
c = {'e':'f'}
def Merge(n):
  m = {}
  for i in range(len(n)):
    m.update({i+1:n[i]})
  return m
print(Merge([a,b,c]))
相关问题