【问题标题】:merger two dict in python like this像这样在python中合并两个dict
【发布时间】:2016-03-16 08:34:43
【问题描述】:

我想像这样合并两个字典:

来自:

  a1 = {u'2016-03-11': [u'20:00', u'22:10']}
  a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}

到:

  an = {u'2016-03-11': [u'20:00',u'22:10', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}

我需要一个函数合并两个字典

【问题讨论】:

    标签: python dictionary merge


    【解决方案1】:
    from collections import defaultdict
    
    
    a1 = {u'2016-03-11': [u'20:00', u'22:10']}
    a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}    
    
    dd = defaultdict(set)
    for d in a1, a2:
        for k, v in d.items():
            dd[k] |= set(v)
    res = {k: sorted(v) for k, v in dd.items()}
    
    print(res)
    # {'2016-03-12': ['20:00', '22:10'], '2016-03-11': ['20:00', '22:10', '23:10']}
    

    【讨论】:

    • sorted(list(v)) 可以简化为sorted(v)
    【解决方案2】:
    a1 = {u'2016-03-11': [u'20:00', u'22:10']}
    a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}
    
    
    import copy
    an = copy.deepcopy(a1)
    
    for key, value in a2.iteritems():
        if key in an:
            an[key] = list(set(an[key] + a2[key]))
        else:
            an[key] = value
    
    print an
    
    >> {u'2016-03-11': [u'22:10', u'20:00', u'23:10'], u'2016-03-12': [u'20:00', u'22:10']}
    

    【讨论】:

      【解决方案3】:

      使用setsorted将两个列表合二为一并进行排序:

      >>> a1 = {u'2016-03-11': [u'20:00', u'22:10']}
      >>> a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}
      
      
      >>> an = {}
      >>> for d in a1, a2:
      ...     for key in d:
      ...         an[key] = sorted(set(an.get(key, []) + d[key]))
      ...         # ^^  Merge two lists (dictionary values) into one, and sort
      ... 
      >>> print an
      {u'2016-03-11': [u'20:00', u'22:10', u'23:10'],
       u'2016-03-12': [u'20:00', u'22:10']}
      

      更新

      使用字典理解的替代版本(假设只合并两个字典):

      >>> {key: sorted(set(a1.get(key,[]) + a2.get(key,[]))) for key in set(a1)|set(a2)}
      {u'2016-03-11': [u'20:00', u'22:10', u'23:10'],
       u'2016-03-12': [u'20:00', u'22:10']}
      

      【讨论】:

      • 如果不使用'for',我该怎么办??
      • @VityLin,您需要以任何方式迭代字典。这是不可避免的。
      • @VityLin,我添加了一个不使用for循环的版本,而是字典理解。 (但它仍在迭代)
      【解决方案4】:
      a1 = {u'2016-03-11': [u'20:00', u'22:10']}
      a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}
      
      
      an = a1
      
      for key in a2 :
          if key in an :
              an[key] = list(set(a2[key]+ a2[key]))
              an[key].sort()
          else :
              x = {key : a2[key]}
              an.update(x)
      
      keyList = an.keys()
      keyList.sort()
      temp = {}
      for key in keyList:
          temp.update({key:an[key]})
      
      an = temp 
      print an
      

      【讨论】:

        【解决方案5】:

        我派生了这个选项(作为答案发布在这里):

        an = {}
        for key in set().union(a1, a2): 
            an[key] = sorted(set().union(a1.get(key, []), a2.get(key, [])))
        

        它构建没有列表连接的集合。

        它产生所需的结果:

        >>> a1 = {u'2016-03-11': [u'20:00', u'22:10']}
        >>> a2 = {u'2016-03-11': [u'20:00', u'23:10'],u'2016-03-12': [u'20:00', u'22:10']}
        >>> an = {}
        >>> for key in set().union(a1, a2): 
        ...     an[key] = sorted(set().union(a1.get(key, []), a2.get(key, [])))
        ... 
        >>> an
        {u'2016-03-11': [u'20:00', u'22:10', u'23:10'], u'2016-03-12': [u'20:00', u'22:10']}
        

        【讨论】:

          【解决方案6】:

          它看起来很糟糕,但它确实有效:

          an = {}
          for key in set(list(a1.keys()) + list(a2.keys())):
              an[key] = list(set((a1.get(key) or []) + (a2.get(key) or [])))
          

          我确信有更聪明和 Pythonic 的方式,不过 :)

          【讨论】:

          • 迭代字典产生键:keys() 不是必需的。使用dict.get(key, default) 而不是dict.get(key) or defaultfor key in set(list(a1) + list(a2)): an[key] = list(set(a1.get(key, []) + a2.get(key, [])))
          • 1. a1.get(key, []) not (a1.get(key) or []) [get take default argument that is used when the key is not found] 2. set().union(a1.keys(), a2.keys()) (or set().union(a1.keys()).union(a2.keys()) if >2.6) not set(list(a1.keys()) + list(a2.keys())) [这避免了创建 3 个列表和 1 个集合交换 1 个空集和最多 2 个部分填充的集]
          • 包括 falsetru 提供的内容:for key in set().union(a1, a2): an[key] = list(set().union(a1.get(key, []), a2.get(key, [])))
          猜你喜欢
          • 2017-01-31
          • 1970-01-01
          • 1970-01-01
          • 2021-10-20
          • 1970-01-01
          • 1970-01-01
          • 2014-12-25
          • 2019-03-01
          • 2017-07-24
          相关资源
          最近更新 更多