How to Implement a PATCH Partial Update Merge Dict in Python

Implements a recursive merge function that applies HTTP PATCH-like partial updates to a nested dictionary while preserving untouched fields.

Easy Python 3.9+ Aug 9, 2026 API design & gRPC 13 views 0 copies

Python code

17 lines
Python 3.9+
import json

def patch_merge(target: dict, patch: dict) -> dict:
    """Simulate HTTP PATCH semantic: shallow-merge patch into a copy of target."""
    merged = target.copy()
    for key, value in patch.items():
        if isinstance(value, dict) and isinstance(merged.get(key), dict):
            merged[key] = patch_merge(merged[key], value)  # recursive nested merge
        else:
            merged[key] = value  # overwrite or add
    return merged

if __name__ == "__main__":
    original = {"name": "Widget", "specs": {"color": "red", "size": 10}, "price": 5}
    partial = {"specs": {"color": "blue"}, "in_stock": True}
    result = patch_merge(original, partial)
    print(json.dumps(result, indent=2))

Output

stdout
{
  "name": "Widget",
  "specs": {
    "color": "blue",
    "size": 10
  },
  "price": 5,
  "in_stock": true
}

How it works

The function starts by copying the target dictionary so the original is never mutated. It then iterates over each patch key-value pair. If both the patch value and the existing target value are dictionaries, it recursively merges them so nested fields that aren't mentioned in the patch are kept. Otherwise, the patch value overwrites the target value or is added as a new key. This mirrors the semantic of a REST PATCH request where missing fields in the payload are left unchanged. The depth-first recursion handles arbitrarily nested structures correctly.

Common mistakes

  • Mutating the original dict by using `merged = target` instead of `target.copy()`.
  • Using a shallow merge (`{**target, **patch}`) which replaces nested dicts entirely.
  • Forgetting to handle non-dict values in nested patches like lists or primitives.

Variations

  1. Use `copy.deepcopy(target)` if the target contains mutable objects like lists that should be cloned too.
  2. Use the `dpath` library for path-based merging with dot-notation key updates.

Real-world use cases

  • Applying partial updates from a client to a resource in an API backend without losing existing nested fields.
  • Patching representation state transfer (REST) resources in microservices where only some attributes change in a request.
  • Syncing configuration files or settings where a user sends only changed sub-sections to avoid overwrites.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from API design & gRPC

Related tutorials and quizzes for this topic.