Skip to content

Dictionaries

merge_dict(original, updates, merge_functions=None, post_processor=None, key_order=None)

Merge two dictionaries.

Parameters:

Name Type Description Default
original dict

Original dictionary

required
updates dict

Dictionary with updates

required
merge_functions dict[str, Callable[[Any, Any], Any]] | None

Dictionary of functions to use for merging specific keys

None
post_processor callable | None

Function to process the result after merging

None
key_order list[str] | None

Non-exhaustive list of keys to sort by

None

Returns:

Name Type Description
dict dict

Merged dictionary

Example
original = {
    "name": "Alice",
    "age": 30,
    "tags": ["user"],
}
updates = {
    "age": 31,
    "tags": ["editor"],
}
merged = merge_dict(
    original,
    updates,
    merge_functions={
        "age": lambda o, u: min(o, u),
    },
    post_processor=lambda d: d.update({"name": d["name"].upper()})
)
assert merged == {
    "name": "ALICE",
    "age": 30,
    "tags": ["user", "editor"],
}
Source code in src/fuso/dicts.py
def merge_dict(
    original: dict | None,
    updates: dict | None,
    merge_functions: dict[str, Callable[[Any, Any], Any]] | None = None,
    post_processor: Callable[[dict], dict] | None = None,
    key_order: list[str] | None = None,
) -> dict:
    """Merge two dictionaries.

    Args:
        original (dict): Original dictionary
        updates (dict): Dictionary with updates
        merge_functions (dict[str, Callable[[Any, Any], Any]] | None):
            Dictionary of functions to use for merging specific keys
        post_processor (callable | None): Function to process the result after merging
        key_order (list[str] | None): Non-exhaustive list of keys to sort by

    Returns:
        dict: Merged dictionary

    Example:
        ```py
        original = {
            "name": "Alice",
            "age": 30,
            "tags": ["user"],
        }
        updates = {
            "age": 31,
            "tags": ["editor"],
        }
        merged = merge_dict(
            original,
            updates,
            merge_functions={
                "age": lambda o, u: min(o, u),
            },
            post_processor=lambda d: d.update({"name": d["name"].upper()})
        )
        assert merged == {
            "name": "ALICE",
            "age": 30,
            "tags": ["user", "editor"],
        }
        ```
    """
    if merge_functions is None:
        merge_functions = {}
    original = original or {}
    updates = updates or {}
    result = {}
    all_keys = set(original.keys()).union(updates.keys())
    for key in all_keys:
        original_value = original.get(key)
        update_value = updates.get(key)
        merge_function = merge_functions.get(key)
        if merge_function:
            result[key] = merge_function(original_value, update_value)
        elif update_value is None:
            result[key] = original_value
        else:
            result[key] = _merge(original_value, update_value)
    if post_processor:
        result = post_processor(result)
    return sort_dict(result, key_order=key_order)