from collections.abc import MutableMapping, MutableSequence
from copy import deepcopy


def recursive_merge(a, b):
    if type(a) is not type(b):
        return b
    if isinstance(a, MutableMapping):
        for k, v in b.items():
            if k in a:
                a[k] = merge_dicts(a[k], v)
            else:
                a[k] = v
    elif isinstance(a, MutableSequence):
        for i, v in enumerate(b):
            if i < len(a):
                a[i] = merge_dicts(a[i], v)
            else:
                a.append(v)
    else:
        return b
    return a


def merge_dicts(a, b):
    # merge a and b preferring b when items differ
    return recursive_merge(deepcopy(a), deepcopy(b))  # do not change the passed mutables
