If I have 2 dicts as follows:
d1 = {(\'unit1\',\'test1\'):2,(\'unit1\',\'test2\'):4}
d2 = {(\'unit1\',\'test1\'):2,(\'unit1\',\'test2\'):\'\'}
to do this we can just create a dict without the empty values and then merge them together this way:
d1 = {'a':1, 'b':1, 'c': '', 'd': ''}
d2 = {'a':2, 'c':2, 'd': ''}
merged_non_zero = {
k: (d1.get(k) or d2.get(k))
for k in set(d1) | set(d2)
}
print(merged_non_zero)
outputs:
{'a': 1, 'b': 1, 'c': 2, 'd': ''}
a
-> prefer first value from d1 as 'a' exists on both d1 and d2b
-> only exists on d1c
-> non-zero on d2d
-> empty string on bothThe above code will create a dictionary using dict comprehension.
if d1
has the value and its non-zero value (i.e. bool(val) is True
), it'll use d1[k]
value, otherwise it'll take d2[k]
.
notice that we also merge all keys of the two dicts as they may not have the exact same keys using set union - set(d1) | set(d2)
.
unless using obsolete version of python you better off using this.
Pythonic & faster way for dict unpacking:
d1 = {'a':1, 'b':1}
d2 = {'a':2, 'c':2}
merged = {**d1, **d2} # priority from right to left
print(merged)
{'a': 2, 'b': 1, 'c': 2}
its simpler and also faster than the dict(list(d2.items()) + list(d1.items()))
alternative:
d1 = {i: 1 for i in range(1000000)}
d2 = {i: 2 for i in range(2000000)}
%timeit dict(list(d1.items()) + list(d2.items()))
402 ms ± 33.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit {**d1, **d2}
144 ms ± 1.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
more on this from PEP448:
The keys in a dictionary remain in a right-to-left priority order, so {**{'a': 1}, 'a': 2, **{'a': 3}} evaluates to {'a': 3}. There is no restriction on the number or position of unpackings.