How to merge multiple dicts with same key?

前端 未结 14 2375
别跟我提以往
别跟我提以往 2020-11-22 13:12

I have multiple dicts/key-value pairs like this:

d1 = {key1: x1, key2: y1}  
d2 = {key1: x2, key2: y2}  

I want the result to be a new di

相关标签:
14条回答
  • 2020-11-22 13:43

    If keys are nested:

    d1 = { 'key1': { 'nkey1': 'x1' }, 'key2': { 'nkey2': 'y1' } } 
    d2 = { 'key1': { 'nkey1': 'x2' }, 'key2': { 'nkey2': 'y2' } }
    
    ds = [d1, d2]
    d = {}
    for k in d1.keys():
        for k2 in d1[k].keys():
            d.setdefault(k, {})
            d[k].setdefault(k2, [])
            d[k][k2] = tuple(d[k][k2] for d in ds)
    

    yields:

    {'key1': {'nkey1': ('x1', 'x2')}, 'key2': {'nkey2': ('y1', 'y2')}}
    
    0 讨论(0)
  • 2020-11-22 13:48

    This method merges two dicts even if the keys in the two dictionaries are different:

    def combine_dict(d1, d2):
        combined = {}
        for k in set(d1.keys()) | set(d2.keys()):
            combined[k] = tuple(d[k] for d in [d1, d2] if k in d)
        return combined
    

    Example:

    d1 = {
        'a': 1,
        'b': 2,
    }
    d2` = {
        'b': 'boat',
        'c': 'car',
    }
    combine_dict(d1, d2)
    # Returns: {
    #    'a': (1,),
    #    'b': (2, 'boat'),
    #    'c': ('car',)
    # }
    
    0 讨论(0)
  • 2020-11-22 13:49

    assuming all keys are always present in all dicts:

    ds = [d1, d2]
    d = {}
    for k in d1.iterkeys():
        d[k] = tuple(d[k] for d in ds)
    

    Note: In Python 3.x use below code:

    ds = [d1, d2]
    d = {}
    for k in d1.keys():
      d[k] = tuple(d[k] for d in ds)
    

    and if the dic contain numpy arrays:

    ds = [d1, d2]
    d = {}
    for k in d1.keys():
      d[k] = np.concatenate(list(d[k] for d in ds))
    
    0 讨论(0)
  • 2020-11-22 13:50
    dict1 = {'m': 2, 'n': 4}
    dict2 = {'n': 3, 'm': 1}
    

    Making sure that the keys are in the same order:

    dict2_sorted = {i:dict2[i] for i in dict1.keys()}
    
    keys = dict1.keys()
    values = zip(dict1.values(), dict2_sorted.values())
    dictionary = dict(zip(keys, values))
    

    gives:

    {'m': (2, 1), 'n': (4, 3)}
    
    0 讨论(0)
  • 2020-11-22 13:54

    From blubb answer:

    You can also directly form the tuple using values from each list

    ds = [d1, d2]
    d = {}
    for k in d1.keys():
      d[k] = (d1[k], d2[k])
    

    This might be useful if you had a specific ordering for your tuples

    ds = [d1, d2, d3, d4]
    d = {}
    for k in d1.keys():
      d[k] = (d3[k], d1[k], d4[k], d2[k]) #if you wanted tuple in order of d3, d1, d4, d2
    
    0 讨论(0)
  • 2020-11-22 13:57

    To supplement the two-list solutions, here is a solution for processing a single list.

    A sample list (NetworkX-related; manually formatted here for readability):

    ec_num_list = [((src, tgt), ec_num['ec_num']) for src, tgt, ec_num in G.edges(data=True)]
    
    print('\nec_num_list:\n{}'.format(ec_num_list))
    ec_num_list:
    [((82, 433), '1.1.1.1'),
      ((82, 433), '1.1.1.2'),
      ((22, 182), '1.1.1.27'),
      ((22, 3785), '1.2.4.1'),
      ((22, 36), '6.4.1.1'),
      ((145, 36), '1.1.1.37'),
      ((36, 154), '2.3.3.1'),
      ((36, 154), '2.3.3.8'),
      ((36, 72), '4.1.1.32'),
      ...] 
    

    Note the duplicate values for the same edges (defined by the tuples). To collate those "values" to their corresponding "keys":

    from collections import defaultdict
    ec_num_collection = defaultdict(list)
    for k, v in ec_num_list:
        ec_num_collection[k].append(v)
    
    print('\nec_num_collection:\n{}'.format(ec_num_collection.items()))
    ec_num_collection:
    [((82, 433), ['1.1.1.1', '1.1.1.2']),   ## << grouped "values"
    ((22, 182), ['1.1.1.27']),
    ((22, 3785), ['1.2.4.1']),
    ((22, 36), ['6.4.1.1']),
    ((145, 36), ['1.1.1.37']),
    ((36, 154), ['2.3.3.1', '2.3.3.8']),    ## << grouped "values"
    ((36, 72), ['4.1.1.32']),
    ...] 
    

    If needed, convert that list to dict:

    ec_num_collection_dict = {k:v for k, v in zip(ec_num_collection, ec_num_collection)}
    
    print('\nec_num_collection_dict:\n{}'.format(dict(ec_num_collection)))
      ec_num_collection_dict:
      {(82, 433): ['1.1.1.1', '1.1.1.2'],
      (22, 182): ['1.1.1.27'],
      (22, 3785): ['1.2.4.1'],
      (22, 36): ['6.4.1.1'],
      (145, 36): ['1.1.1.37'],
      (36, 154): ['2.3.3.1', '2.3.3.8'],
      (36, 72): ['4.1.1.32'],
      ...}
    

    References

    • [this thread] How to merge multiple dicts with same key?
    • [Python docs] https://docs.python.org/3.7/library/collections.html#collections.defaultdict
    0 讨论(0)
提交回复
热议问题