Search code examples
pythondictionarykey-value

Merge two dictionaries and add custom value if key not present


Given two dictionaries, I want to merge them together by adding values, but add a custom value if one of the keys is not present in both the dictionaries. For example with these two dictionaries and val=5.

val = 5 
dict1 = {1:0, 2:3, 3:12, 4:2, 5:7}
dict2 = {2:4, 3:3, 1:12, 7:4, 8:2}

the result should be:

result = {1:12, 2:7, 3:15, 4:7, 5:12, 7:9, 8:7}

In this case, 1 2 and 3 were all in both dictionaries, so their value got summed. However for 4 5 7 and 8, the value of val was added in addition to their value from one of the dictionaries.

Is there any fast pythonic way to do this without having to go through awkward iterations both ways (i.e. dict1 checks for dict2 vals and vice versa)? Any help is appreciated!


Solution

  • An easy to understand solution:

    val = 5
    dict1 = {1: 0, 2: 3, 3: 12, 4: 2, 5: 7}
    dict2 = {2: 4, 3: 3, 1: 12, 7: 4, 8: 2}
    
    # get list of merged keys from both dicts
    keys = set(dict1)
    keys.update(dict2)
    
    result = {}
    for k in keys:
        if k in dict1:  # key is in `dict1`
            result[k] = dict1[k] + dict2.get(k, val)
        else:  # if key is not in `dict1`, then it *must* be in `dict2`
            result[k] = dict2[k] + val
    
    print(result)
    

    But, note this following part:

    if k in dict1:
        result[k] = dict1[k] + dict2.get(k, val)
    else:
        result[k] = dict2[k] + val
    

    It can actually be simplified down to one line if needed:

    result[k] = dict1.get(k, val) + dict2.get(k, val)
    

    Now, observe the modified for loop:

    result = {}
    for k in set(dict1) | dict2.keys():
        result[k] = dict1.get(k, val) + dict2.get(k, val)
    

    It can be simplified again to one line (if needed) using a dict comprehension:

    result = {k: dict1.get(k, val) + dict2.get(k, val) for k in set(dict1) | dict2.keys()}
    

    The result is:

    {1: 12, 2: 7, 3: 15, 4: 7, 5: 12, 7: 9, 8: 7}