Example #1
0
def merge_dicts_smart(target: dict, source: dict, sep='/'):
    target_flatten = dict_flatten(target)
    mapping = defaultdict(list)
    for k, v in target_flatten.items():
        parts = k.split(sep)
        for i in range(len(parts) - 1, -1, -1):
            key = sep.join(parts[i:])
            mapping[key].append(k)

    for k, v in source.items():
        assert len(mapping[k]) == 1, f'ambiguous mapping for {k}'
        key = mapping[k][0]
        target_flatten[key] = v

    return dict_unflatten(target_flatten)
Example #2
0
def merge_dicts_smart(target: dict, source: dict, sep='/'):
    target_flatten = dict_flatten(target)
    mapping = defaultdict(list)
    hooks = dict()

    for k, v in target_flatten.items():
        parts = k.split(sep)
        for i in range(len(parts) - 1, -1, -1):
            key = sep.join(parts[i:])
            mapping[key].append(k)

            if i < len(parts) - 1:
                hooks[sep.join(parts[i:-1])] = sep.join(parts[:i + 1])

    for k, v in list(source.items()):
        if isinstance(v, dict):
            source.update(
                {k + sep + kk: vv
                 for kk, vv in dict_flatten(v).items()})

    for k, v in source.items():
        if len(mapping[k]) == 0:
            parts = k.split(sep)
            hook = None
            for i in range(len(parts) - 1, -1, -1):
                h = sep.join(parts[:i])
                if h in hooks:
                    hook = hooks[h] + sep + sep.join(parts[i:])
                    break

            if not hook:
                hook = k

            mapping[k] = [hook]
        assert len(mapping[k]) == 1, f'ambiguous mapping for {k}'
        key = mapping[k][0]
        target_flatten[key] = v

    return dict_unflatten(target_flatten)