libb.merge_dict

merge_dict(old, new, inplace=True)[source]

Recursively merge two dictionaries, including nested dictionaries and iterables.

This function performs a deep merge of new into old, handling nested dictionaries, iterables (like lists and tuples), and type mismatches gracefully.

Parameters:
  • old (dict) – The dictionary to merge into (will be modified if inplace=True).

  • new (dict) – The dictionary to merge from (remains unchanged).

  • inplace (bool) – If True, modifies old in place; if False, returns a new merged dict.

Return type:

dict[str, Any] | None

Returns:

If inplace=False, returns the merged dictionary. Otherwise, returns None.

Basic Nested Merge:

>>> l1 = {'a': {'b': 1, 'c': 2}, 'b': 2}
>>> l2 = {'a': {'a': 9}, 'c': 3}
>>> merge_dict(l1, l2, inplace=False)
{'a': {'b': 1, 'c': 2, 'a': 9}, 'b': 2, 'c': 3}
>>> l1=={'a': {'b': 1, 'c': 2}, 'b': 2}
True
>>> l2=={'a': {'a': 9}, 'c': 3}
True

Multilevel Merging:

>>> xx = {'a': {'b': 1, 'c': 2}, 'b': 2}
>>> nice = {'a': {'a': 9}, 'c': 3}
>>> merge_dict(xx, nice)
>>> 'a' in xx['a']
True
>>> 'c' in xx
True

Values Get Overwritten:

>>> warn = {'a': {'c': 9}, 'b': 3}
>>> merge_dict(xx, warn)
>>> xx['a']['c']
9
>>> xx['b']
3

Merges Iterables (preserving types when possible):

>>> l1 = {'a': {'c': [5, 2]}, 'b': 1}
>>> l2 = {'a': {'c': [1, 2]}, 'b': 3}
>>> merge_dict(l1, l2)
>>> len(l1['a']['c'])
4
>>> l1['b']
3

Handles Type Mismatches (converts to lists):

>>> l1 = {'a': {'c': [5, 2]}, 'b': 1}
>>> l3 = {'a': {'c': (1, 2,)}, 'b': 3}
>>> merge_dict(l1, l3)
>>> len(l1['a']['c'])
4
>>> isinstance(l1['a']['c'], list)
True

Handles None Values:

>>> l1 = {'a': {'c': None}, 'b': 1}
>>> l2 = {'a': {'c': [1, 2]}, 'b': 3}
>>> merge_dict(l1, l2)
>>> l1['a']['c']
[1, 2]