Home > Mobile >  How to join two dictionaries using simple code?
How to join two dictionaries using simple code?

Time:12-12

I would like to join two dictionaries using Python. Given:

dict_keys = {"A": ["A1", "A2"], "B": ["B1", "B2"], "C": ["C1"]}

dict_values1 = {"A1": [1, 2, 3, 4], "A2": [5, 6, 7], "B1": [8, 9], "B2": [10], "C1" : [11, 12, 13]}

dict_values2 = {"A1": ["one", "two", "three", "four"], "A2": ["five", "six", "seven"], "B1": ["eight", "nine"], "B2": ["ten"], "C1": ["eleven", "twelve", "thirteen"]}

I would like to join using the elements in the list of the value of dict_keys with dict_values1 and generate this:

{'A': [1, 2, 3, 4, 5, 6, 7], 'B': [8, 9, 10], 'C': [11, 12, 13]}

I would also like to join using the elements in the list of the value of dict_keys with dict_value2 and generate this:

{'A': ['one', 'two', 'three', 'four', 'five', 'six', 'seven'], 'B': ['eight', 'nine', 'ten'], 'C': ['eleven', 'twelve', 'thirteen']}

The code I wrote is simple:

def join():
    dict_keys = {"A": ["A1", "A2"], "B": ["B1", "B2"], "C": ["C1"]}
    dict_values1 = {"A1": [1, 2, 3, 4], "A2": [5, 6, 7], "B1": [8, 9], "B2": [10], "C1" : [11, 12, 13]}
    dict_values2 = {"A1": ["one", "two", "three", "four"], "A2": ["five", "six", "seven"], "B1": ["eight", "nine"], "B2": ["ten"], "C1": ["eleven", "twelve", "thirteen"]}

    result1 = {}
    result2 = {}
    for master_key, keys in dict_keys.items():
        values1 = []
        values2 = []

        for key in keys:
            values1.extend(dict_values1[key])
            values2.extend(dict_values2[key])

        result1[master_key] = values1
        result2[master_key] = values2

    return result1, result2

However, I think this implementation is not very "Python". So I changed it using comprehension:

 def join():
    dict_keys = {"A": ["A1", "A2"], "B": ["B1", "B2"], "C": ["C1"]}
    dict_values1 = {"A1": [1, 2, 3, 4], "A2": [5, 6, 7], "B1": [8, 9], "B2": [10], "C1" : [11, 12, 13]}
    dict_values2 = {"A1": ["one", "two", "three", "four"], "A2": ["five", "six", "seven"], "B1": ["eight", "nine"], "B2": ["ten"], "C1": ["eleven", "twelve", "thirteen"]}

    result1 = {master_key: sum([dict_values1[key] for key in keys], []) for master_key, keys in dict_keys.items()}
    result2 = {master_key: sum([dict_values2[key] for key in keys], []) for master_key, keys in dict_keys.items()}

    return result1, result2

The problem of this implementation is that it needs to iterate through the dict_keys twice. But this is the farest I can get.

Can someone let me know if there are simpler and cleaner way to achieve this using just one iteration on dict_keys?

CodePudding user response:

Use dict.setdefault method:

def dict_join(dict_keys, dict_values1):    
    d1 = {}
    for k,v in dict_keys.items():
        for x in v:
            d1.setdefault(k,[]).extend(dict_values1[x])
    return d1



result1 = dict_join(dict_keys, dict_values1)
result2 = dict_join(dict_keys, dict_values2)

Output:

{'A': [1, 2, 3, 4, 5, 6, 7], 'B': [8, 9, 10], 'C': [11, 12, 13]}

{'A': ['one', 'two', 'three', 'four', 'five', 'six', 'seven'],
 'B': ['eight', 'nine', 'ten'],
 'C': ['eleven', 'twelve', 'thirteen']}

CodePudding user response:

I can't think of great names today...

def do_it(keys, values):
    from itertools import chain
    for out_key, keys in keys.items():
        yield out_key, list(chain.from_iterable(values[key] for key in keys))

print(dict(do_it(dict_keys, dict_values1)))
print(dict(do_it(dict_keys, dict_values2)))

Output:

{'A': [1, 2, 3, 4, 5, 6, 7], 'B': [8, 9, 10], 'C': [11, 12, 13]}
{'A': ['one', 'two', 'three', 'four', 'five', 'six', 'seven'], 'B': ['eight', 'nine', 'ten'], 'C': ['eleven', 'twelve', 'thirteen']}
  • Related