# Adding values from two dictionaries of integers

Is this the correct way of adding the values of two dictionaries? It seems to me that the test for an empty dictionary is superfluous but I'm not sure.

`mymodule.py`

``````def merge(dict_1: Union[Dict[str, int], None], dict_2: Union[Dict[str, int], None]) -> dict:
"""
Merge 2 dicts of ints: keys from both dicts, values are the sum of values (one dict can be None).
:dict_1: {"a": 1, "b": 2}
:dict_2: {"a": 3, "c": 3} or None
:return: {"a": 4, "b": 2, "c": 3} or {"a": 1, "b": 2}
"""
if dict_2 is None:
return dict_1
elif dict_1 is None:
return dict_2
result = dict()

for key in dict_1.keys() | dict_2.keys():  # union of all keys
result[key] = dict_1.get(key, 0) + dict_2.get(key, 0)  # sum quantities or 0 if key not found

return result
``````

`mymodule_test.py`

``````import unittest

import mymodule

class TestMerge(unittest.TestCase):
def test_merge(self) -> None:
dict_1 = {"a": 1, "b": 2}
dict_2 = {"a": 3, "c": 3}
expected = {"a": 4, "b": 2, "c": 3} or {"a": 1, "b": 2}
actual = bestdeck.merge(dict_1, dict_2)
assert expected == actual
def test_empty_merge(self) -> None:
dict_1 = {"a": 1, "b": 2}
dict_2 = None
expected = dict_1
actual = bestdeck.merge(dict_1, dict_2)
assert expected == actual

if __name__ == '__main__':
unittest.main()
``````

edited

+1 vote

Yes if you expect `NoneType` as input, it's perfectly fine to check the types

``````def merge(d1, d2):
if d1 is None and d2 is None: return None
if d1 is None: return d2
if d2 is None: return d1

return { key: d1.get(key, 0) + d2.get(key, 0) for key in d1.keys() | d2.keys() }
``````

But if `NoneType` is expected to be an edge case, an "exception to the rule" rather than a regular input, you could replace `if..else` with `try..except` blocks

``````def merge(d1, d2):
try:
result = dict(d1)
except TypeError:
result = {}

try:
for key, value in d2.items():
result[key] = result.get(key, 0) + value
except AttributeError:
pass

return result
``````

They are different styles (LBYL vs EAFP) and you can use which one is more convenient.

Although for your particular problem that you are describing, there is already a specialized subclass called collections.Counter:

``````from collections import Counter
def merge(d1, d2):
result = Counter(d1)
result.update(d2)
return dict(result)
``````
by
selected