I'm wondering what is the best way to merge 2 dicts into one dict as follows:
dict1 = {k1: v1, k2: v2, ...}and dict2 = {v1: w1, v2: w2, ...}into
result = {k1: w1, k2: w2, ...}
I already have a solution using dict comprehension:
result = {
k: dict2[v]
for k, v in dict1.items()
}
But I don't think this is the most elegant way to do it. Can you please help me ?
As an alternative/extension, to @jpp's answer, you could also use reduce/functools.reduce to get a slightly more condensed form of the chainer function:
from functools import reduce
def chainer(first, *others):
return {k: reduce(lambda x, d: d[x], others, v) for k, v in first.items()}
Which of those is better is mainly a matter of taste; usage and results are the same.
For just two dictionaries, your dictionary comprehension is IMHO as good and elegant as it gets. You might want to use get or add a condition in case a key is not present in the second dict, though.
>>> dict1 = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
>>> dict2 = {'v1': 'w1', 'v2': 'w2'}
>>> {k: dict2.get(v, 'undefined') for k, v in dict1.items()}
{'k1': 'w1', 'k2': 'w2', 'k3': 'undefined'}
>>> {k: dict2[v] for k, v in dict1.items() if v in dict2}
{'k1': 'w1', 'k2': 'w2'}
Adding a safeguard like this into the chainer is a bit more involved, in particular for this variant using reduce (and might not be necessary at all).
For the two-dictionary case, your dictionary comprehension is fine. This assumes you can guarantee your values in dict1 are keys in dict2.
Considering how you can extend this to arbitrary dictionary inputs, you can use a for loop:
dict1 = {'k1': 'v1', 'k2': 'v2'}
dict2 = {'v1': 'w1', 'v2': 'w2'}
dict3 = {'w1': 'x1', 'w2': 'x2'}
def chainer(first, *others):
res = first.copy() # make a copy to avoid overwriting dict1
for k, v in res.items():
for dct in others:
v = dct[v]
res[k] = v
return res
res = chainer(dict1, dict2, dict3)
# {'k1': 'x1', 'k2': 'x2'}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With