Fold a list of small mappings without mutation

A sequence of small configuration mappings can be folded left to right with functools.reduce(). The operator.or_ function applies the mapping-union operator (|) at each step. Its left-to-right order gives later layers precedence, so the second mapping replaces retries: 1 with retries: 3. Starting with {} is important: it supplies a defined result for an empty layers list and makes the accumulator a dictionary from the first operation onward.

For dictionaries, left | right creates a new dictionary instead of updating left. The assertion after the reduction therefore checks the merged contents, confirms that the first source layer still has retries: 1, and confirms the final result is not that source dictionary. The printed order follows insertion order: replacing an existing key does not move it, while mode is appended.

This is convenient for a few shallow mappings. Nested dictionaries are values, not recursively merged structures: a later {"database": {"port": 5432}} replaces the whole earlier database dictionary. It also allocates a fresh dictionary at every reduction step, so a simple loop with result = result | layer, or a carefully authorized mutable update, can be clearer for large collections. Inputs should not be changed during the fold.

AI assistance was used in preparing this Batu Lab Notes article.

from functools import reduce
from operator import or_


layers = [
    {"host": "cache", "retries": 1},
    {"retries": 3},
    {"mode": "safe"},
]
merged = reduce(or_, layers, {})
assert merged == {"host": "cache", "retries": 3, "mode": "safe"}
assert layers[0] == {"host": "cache", "retries": 1}
assert merged is not layers[0]
print(merged)

Expected stdout:

{'host': 'cache', 'retries': 3, 'mode': 'safe'}

Sources

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic