pythonmergeddictionaries

Merging dictionaries not including duplicate values in python


I would like to merge two dictionaries, but if they have the same key, I would only merge non-duplicate values.

The following code works, but I have a question if it's possible to rewrite this when trying to get a union by using | or (**dict1, **dict2)? When I tried using |, my output would be from this dict_merge({ 'A': [1, 2, 3] }, { 'A': [2, 3, 4] }) to this {'A': [2, 3, 4]}

def dict_merge(dict1, dict2):
    

    for key in dict2.keys():
        if key in dict1.keys():

            d3 = dict1[key] + dict2[key]
            d3 = set(d3)
            dict1[key] = list(d3)

        else:
            dict1[key] = dict2[key]
    return dict1

dict_merge({ 'A': [1, 2, 3] }, { 'B': [2, 4, 5, 6]})

Output

{ 'A': [1, 2, 3], 'B': [2, 4, 5, 6] }

Solution

  • Giving your two dictionaries names, let's get the union of their keys.

    >>> d1 = { 'A': [1, 2, 3] }
    >>> d2 = { 'A': [2, 3, 4] }
    >>> d1.keys() | d2.keys()
    {'A'}
    

    Assuming the lists are really sets based on your code, we can now iterate over the union of the keys in a dictionary comprehension, and union those two sets and turning them back into a list.

    >>> {k: list(set(d1.get(k, [])) | set(d2.get(k, []))) for k in d1.keys() | d2.keys()}
    {'A': [1, 2, 3, 4]}
    

    If we incorporate some more interesting dictionaries and repeat the same dictionary comprehension:

    >>> d1 = {'A': [1,2,3], 'B': [4,5,6]}
    >>> d2 = {'B': [5,6,7,8], 'C': [9,10]}
    >>> {k: list(set(d1.get(k, [])) | set(d2.get(k, []))) for k in d1.keys() | d2.keys()}
    {'C': [9, 10], 'A': [1, 2, 3], 'B': [4, 5, 6, 7, 8]}