【问题标题】:Python: issue trying to merge two dictionaries in which values must be added upPython:尝试合并两个必须相加值的字典时出现问题
【发布时间】:2021-02-09 00:22:13
【问题描述】:

我对 Python 非常陌生,并且坚持完成我正在学习的在线课程的任务。我对 Python 的了解非常有限。

这里是任务:''' 编写一个脚本,包含以下两个 字典并通过组合公共键创建一个新字典 并将重复键的值加在一起。请使用 For 循环 遍历这些字典以完成此任务。

输入/输出示例:

dict_1 = {"a": 1, "b": 2, "c": 3} dict_2 = {"a": 2, "c": 4, "d": 2}

结果 = {"a": 3, "b": 2, "c": 7, "d": 2}

'''

dict_2 = {"a": 2, "c": 4 , "d": 2}
dict_3 = {}


for x, y in dict_1.items():
    for z, h in dict_2.items():
        if x == z:
            dict_3[x] = (y + h)
        else:
            dict_3[x] = (y)
            dict_3[z] = (h)

print(dict_3)

错误的输出:

{'a': 2, 'c': 3, 'd': 2, 'b': 2}

一切都在工作,直到“其他”条件。 我试图只隔离两个字典的唯一出现,但结果实际上覆盖了我之前在条件下添加到字典中的内容。 你知道一种方法来隔离每个字典的单一事件吗?我想您可以计算它们并添加“如果计数为 1”条件,但我不能碰巧做到这一点。谢谢!

【问题讨论】:

  • 为什么不将所有 dict_1 项插入到 dict_3 中,然后简单地迭代 dict_2,测试每个键是否已经在 dict_3 中,然后根据需要添加/插入。它会更快更简单。
  • 你的方法是错误的。你不应该以 O(n*m) 的复杂度来做,在 O(n+m) 的情况下做这件事就足够简单了。如果不计算 dict_2 到 dict_3 的复制,那么它甚至会是 O(m)。

标签: python dictionary merge


【解决方案1】:
dict_1 = {"a": 1, "b": 2, "c": 3} 
dict_2 = {"a": 2, "c": 4 , "d": 2}

key_list = {*dict_1, *dict_2}
sum ={}
for key in key_list:
 sum[key] = dict_1.get(key, 0) + dict_2.get(key, 0)
print(sum)

#{'a': 3, 'c': 7, 'd': 2, 'b': 2}

【讨论】:

    【解决方案2】:

    不是最优雅或最有效的解决方案,但一种直观的方法是提取唯一键列表,然后迭代新的键列表以从两个字典中提取和附加值。

    dict_1 = {"a": 1, "b": 2, "c": 3} 
    dict_2 = {"a": 2, "c": 4 , "d": 2}
    result = {}
    
    # Extract the unique keys from both dicts
    keys = set.union(set(dict_1.keys()), set(dict_2.keys()))
    
    # Initialize the values of the result dictionary
    for key in sorted(keys):
        result[key] = 0
    
    # Append the values of dict_1 and dict_2 to result if key is present
    for key in keys:
        if key in dict_1:
            result[key] += dict_1[key]
        
        if key in dict_2:
            result[key] += dict_2[key]
    
    print(result)
    

    这将打印:{'a': 3, 'b': 2, 'c': 7, 'd': 2}

    【讨论】:

    • 要提取唯一键,只需使用keys = {*dict_1, *dict_2}
    • 你正在做的简短版本是:result = {k: dict_1.get(k, 0) + dict_2.get(k, 0) for k in {*dict_1, *dict_2}}
    • @VisioN 这将是一种更好、更有效的方法,我想我是为了清晰起见。
    • 在这种情况下,您不需要将一组键投射到列表中,这没有任何区别。
    • @VisioN 你说得对,我很快就回答了这个问题,并没有过多关注我在做什么。我更专注于试图解释思维过程。不过,我会进行编辑。
    【解决方案3】:

    也许collections.defaultdict 更适合您的目的;当存在它没有的值时,它只会返回您分配给它的默认值并将其放入其“实际”字典中。然后,您可以使用 dict() 函数将其转换回普通字典。

    from collections import defaultdict
    
    dict_1 = {"a": 1, "b": 2, "c": 3} 
    dict_2 = {"a": 2, "c": 4 , "d": 2}
    dict_3 = defaultdict(int)  # provide 0 as the default value
    
    for k, v in dict_1.items():
        dict_3[k] += v
    for k, v in dict_2.items():
        dict_3[k] += v
    print(dict(dict_3))  # convert back to normal dictionary
    

    【讨论】:

    • 对于Python 新手 的人来说,使用defaultdict 可能有点太复杂了。主要信息应发送给算法。
    【解决方案4】:
    dict_1 = {"a": 1, "b": 2, "c": 3}
    dict_2 = {"a": 2, "c": 4 , "d": 2}
    dict_3={}
    for key in dict_1: 
        if key in dict_2: 
            dict_3[key] = dict_2[key] + dict_1[key]
        else:
            dict_3[key]=dict_1[key]
            
    for key in dict_2: 
        if key in dict_1: 
            dict_3[key] = dict_2[key] + dict_1[key]
        else:
            dict_3[key]=dict_2[key]
    
              
    print(dict_3)
    

    【讨论】:

    • 为什么需要第一个if 子句?
    【解决方案5】:

    如果你想避免使用循环,你可以使用字典理解,使用默认值为 0 的 get 以避免遇到 KeyError:

    dict_1 = {"a": 1, "b": 2, "c": 3}
    dict_2 = {"a": 2, "c": 4 , "d": 2}
    
    dict_3 = {key: dict_1.get(key, 0) + dict_2.get(key, 0) for key in set(list(dict_1.keys())+list(dict_2.keys()))}
    >>> {'c': 7, 'b': 2, 'd': 2, 'a': 3}
    

    虽然这可能是不必要的高级。

    【讨论】:

      【解决方案6】:

      对原始代码的这些更改会产生您想要的结果。

      dict_1 = {"a": 1, "b": 2, "c": 3} 
      dict_2 = {"a": 2, "c": 4 , "d": 2}
          
      dict_3 = {}
      
      
      for x, y in dict_1.items():
          if x not in dict_2 and x not in dict_3:
              dict_3[x] = y
          for z, h in dict_2.items():
              if x == z:
                  dict_3[x] = y + h
              elif z not in dict_1 and z not in dict_3:
                  dict_3[z] = h
      
      print(dict_3)
      

      打印:

      {'a': 3, 'd': 2, 'b': 2, 'c': 7}
      

      更简洁的方法是将dict_3 设置为dict_1,然后迭代dict_2

      dict_3 = dict_1.copy()
      
      for key, val in dict_2.items():
          dict_3[key] = dict_3.get(key, 0) + val
      

      dict_3.get(key, 0) 行在dict_3 中获取key 的值,如果它存在于dict_3 中,否则,它提供值0

      【讨论】:

      • 谢谢!这是最接近我已有的,也是我力所能及的。
      猜你喜欢
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      相关资源
      最近更新 更多