【问题标题】:Combining dictionaries within dictionaries & adding values在字典中组合字典并添加值
【发布时间】:2013-11-24 17:37:52
【问题描述】:

我正在尝试组合两个字典以产生如下结果:

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' 的结果执行不同的计算。

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

【问题讨论】:

    标签: python python-3.x dictionary


    【解决方案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] 是一个字典,它会将ret[key] 设置为x[key] 和y[key] 的合并字典。

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

    注意:这不适用于函数。尝试在那里自己解决问题。

    【讨论】:

      【解决方案2】:

      使用collections.Counter 和isinstance:

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

      【讨论】:

      • 很遗憾,我不允许导入任何函数。有没有办法在不导入的情况下进行计数?顺便感谢您的帮助。
      • @user3027711 我添加了另一个解决方案。
      【解决方案3】:

      为了方便,你可以使用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(您可以使用集合来确保键是唯一的,但重复应该不是问题,因为它们会被覆盖)
      • 对于每个键,将旧字典中的值的总和添加到新字典(如果键不存在,您可以使用dict.get() 得到 0)

      【讨论】:

      • 感谢您的快速回复,但是,我不允许导入任何函数,所以我一直在尝试找到一种方法来编写代码来手动实现计数。有什么想法吗?
      • 我添加了一些提示,可以帮助您自行找到解决方案。
      【解决方案4】:
      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
      

      【讨论】:

        【解决方案5】:

        我幼稚的解决方案是:

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

        【讨论】:

          猜你喜欢
          • 2013-03-18
          • 2018-09-22
          • 1970-01-01
          • 2022-07-05
          • 1970-01-01
          • 1970-01-01
          • 2017-08-03
          • 2023-03-20
          • 1970-01-01
          相关资源
          最近更新 更多