'Compare two dict and change keys in second if keys exists as sub-value in first
Need help remapping the keys for d2 if they match the value for id in d1. In case there are keys that are unmatched, drop them.
d1={'A':{'id':'a'},'B':{'id':'b'}}
d2={'a':1,'b':2, 'c':3}
Expected output:
{'A': 1, 'B': 2}
Solution 1:[1]
This is probably what you're after
d1={'A':{'id':'a'},'B':{'id':'b'}}
d2={'a':123,'b':123}
for key, id_map in d1.copy().items(): # view over soft copy won't mutate
try:
d1[key] = d2[id_map["id"]]
except KeyError:
pass
>>> d1
{'A': 123, 'B': 123}
However, unmapped values will remain the same (ie if there is C, but no id in its mapping, or no c in d2..)
>>> d1={'A':{'id':'a'},'B':{'id':'b'},'C':{'id':'c'}}
[..]
>>> d1
{'A': 123, 'B': 123, 'C': {'id': 'c'}}
If you want to discard unmapped values, you could do so here with del d1[key] in the except or simply create a new dict to pack the keys and values into (never added if KeyError is raised)
Alternatively, if this is an error (ie. C must exist), you can simply let KeyError raise to the caller and have it deal with the consequences
Solution 2:[2]
As long as each 'val' appears at most once in d1's subdictionaries (i.e. the key: {'id': val} pairs in d1), you can iterate over d1's items like so:
d1 = {'A': {'id': 'a'}, 'B': {'id': 'b'}, 'C': {'id': 'c'}}
d2 = {'a': 123, 'b': 12, 'd': 8}
d3 = {k: d2[v['id']] for k, v in d1.items() if v['id'] in d2}
print(d3)
>>> {'A': 123, 'B': 12}
Since you need to check all key-value pairs in d1, this is the best you can do in terms of time and space efficiency.
However, if you will be 're-keying' many d2 dictionaries with the same d1, it may be faster to build a reverse-index to reuse:
reverse_mapping = {v['id']: k for k, v in d1.items()}
def rekey(dict_to_rekey, reverse_map):
return {reverse_map[k]: dict_to_rekey[k]
for k in dict_to_rekey.keys() & reverse_map.keys()}
d3 = rekey(d2, reverse_mapping)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ti7 |
| Solution 2 | kcsquared |
