Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing dicts, updating NOT overwriting values [duplicate]

I am not looking for something like this:

How do I merge two dictionaries in a single expression?

Generic way of updating python dictionary without overwriting the subdictionaries

Python: Dictionary merge by updating but not overwriting if value exists

I am looking for something like this:

input:

d1 = {'a': 'a', 'b': 'b'}
d2 = {'b': 'c', 'c': 'd'}

output:

new_dict = {'a': ['a'], 'b': ['b', 'c'], 'c': ['d']}

I have the following code which works but I am wondering if there is a more efficient method:

First, I create a list "unique_vals", where all the values that are present in both dicts are stored. From this, a new dictionary is created which stores all the values present in both dictionaries

unique_vals = []
new_dict = {}
for key in list(d1.keys())+list(d2.keys()) :
    unique_vals = []
    try:
        for val in d1[key]:
            try:
                for val1 in d2[key]:
                    if(val1 == val) and (val1 not in unique_vals):
                        unique_vals.append(val)
            except:
                continue
    except:        
        new_dict[key] = unique_vals
    new_dict[key] = unique_vals

Then, for every value in both dictionaries that are not listed in this new dictionary, these values are appended to the new dictionary.

for key in d1.keys():
      for val in d1[key]:
          if val not in new_dict[key]:
              new_dict[key].append(val)
for key in d2.keys():
    for val in d2[key]:
        if val not in new_dict[key]:
            new_dict[key].append(val)
like image 203
aze45sq6d Avatar asked Jan 25 '23 16:01

aze45sq6d


2 Answers

Maybe with a defaultdict?

>>> d1 = {'a': 'a', 'b': 'b'} 
>>> d2 = {'b': 'c', 'c': 'd'}
>>> from collections import defaultdict                                         
>>>                                                                             
>>> merged = defaultdict(list)                                                  
>>> dicts = [d1, d2]                                                            
>>> for d in dicts: 
...:     for key, value in d.items(): 
...:         merged[key].append(value) 
...:                                                                            
>>> merged                                                                      
defaultdict(list, {'a': ['a'], 'b': ['b', 'c'], 'c': ['d']})

This works with any number of dictionaries in the dicts list.

As a function:

def merge_dicts(dicts):
    merged = defaultdict(list)

    for d in dicts:
        for key, value in d.items():
            merged[key].append(value)

    return merged
like image 172
actual_panda Avatar answered Jan 31 '23 09:01

actual_panda


Here is a far simpler version:

d1 = {'a': 'a', 'b': 'b'}
d2 = {'b': 'c', 'c': 'd'}

new_dict = {key: [value] for key, value in d1.items()}
for key, value in d2.items():
    try:
        new_dict[key].append(value)
    except:
        new_dict[key] = [value]

Output:

{'a': ['a'], 'b': ['b', 'c'], 'c': ['d']}
like image 21
Mathieu Avatar answered Jan 31 '23 11:01

Mathieu