Rename selected mapping fields without mutating the input
Also published in our primary archive.
To rename selected mapping fields without mutating the input, iterate through the original items and construct a new dictionary with each output key selected from a rename map. With {'old_name': 'A', 'count': 2}, mapping old_name to name returns {'name': 'A', 'count': 2} while the original record remains intact.
The failing section deliberately applies pop to record, the caller-owned mapping. Although the resulting mapping has the desired new key, old_name is gone from the caller's object. The corrected comprehension uses renames.get(key, key) only to select an output key; it does not call a mutating dictionary method and writes to a newly created dictionary. The assertions separately capture the destructive result and verify the corrected result against a fresh record.
This is a shallow transformation. If a value is a nested mutable object, the original and renamed dictionaries still refer to that value. Also, two input keys can map to the same output key; in a comprehension, the later item replaces the earlier value. Validate the rename specification first when either condition matters.
Python's mapping reference documents dict.pop, dict.get, and dictionary item views used by this pattern. All operations are long-established Python 3 features, with no special newer minimum version beyond a supported Python 3 release.
AI assistance disclosure: This article was drafted with AI assistance and uses a synthetic, locally reproducible fixture.
Source: Python mapping types — dict.
record = {"old_name": "A", "count": 2}
# Failing transformation: pop changes the caller-owned dictionary.
mutated = record
mutated["name"] = mutated.pop("old_name")
assert mutated == {"name": "A", "count": 2}
assert "old_name" not in record
record = {"old_name": "A", "count": 2}
original_record = record.copy()
renames = {"old_name": "name"}
renamed = {
renames.get(key, key): value
for key, value in record.items()
}
assert renamed == {"name": "A", "count": 2}
assert record == original_record
print("pop changed input:", mutated)
print("input:", record)
print("renamed:", renamed)
pop changed input: {'count': 2, 'name': 'A'}
input: {'old_name': 'A', 'count': 2}
renamed: {'name': 'A', 'count': 2}