Pivot a small in-memory list of records into totals
Pivot a small in-memory list of records into totals
To pivot a small Python list of records into category totals, accumulate each Decimal in defaultdict(Decimal). This creates a zero-valued total for a category on first access, so the result does not depend on prebuilding nested containers for every expected category.
The input has amounts 1.25, 2.25, and 4.00 for categories A, A, and B. The failing loop starts with a nested mapping only for A and updates only keys already present. It produces {'A': '3.50'} and silently omits B; this illustrates how nested mutation can hide an absent category. It also leaves the input untouched, so the contrast is about the aggregation policy rather than an input-side mutation.
The corrected loop uses defaultdict(Decimal) and adds each record's amount directly. It produces {'A': '3.50', 'B': '4.00'}. The result is converted to strings for stable, readable output while the calculation remains in Decimal. The assertion verifies this particular fixture and that the records were not changed; it does not validate money scales, currency compatibility, or an application's rounding policy.
Decimal and defaultdict are established standard-library APIs; no newer Python version is required. Use decimal strings rather than binary floats when constructing exact decimal fixture values. See the decimal documentation and collections documentation.
AI assistance disclosure: this article was drafted with AI assistance and its synthetic example was checked for deterministic output.
from collections import defaultdict
from decimal import Decimal
records = [
{"category": "A", "amount": Decimal("1.25")},
{"category": "A", "amount": Decimal("2.25")},
{"category": "B", "amount": Decimal("4.00")},
]
original_records = [record.copy() for record in records]
# Failure: a prebuilt nested mapping causes an unknown category to be skipped.
bad_totals = {"A": {"amount": Decimal("0")}}
for record in records:
category = record["category"]
if category in bad_totals:
bad_totals[category]["amount"] += record["amount"]
# Correction: first access supplies Decimal(0) for every encountered category.
totals = defaultdict(Decimal)
for record in records:
totals[record["category"]] += record["amount"]
bad_display = {key: str(value["amount"]) for key, value in bad_totals.items()}
corrected_display = {key: str(value) for key, value in totals.items()}
assert records == original_records
assert bad_display == {"A": "3.50"}
assert corrected_display == {"A": "3.50", "B": "4.00"}
print("input unchanged:", records)
print("nested result:", bad_display)
print("defaultdict result:", corrected_display)
input unchanged: [{'category': 'A', 'amount': Decimal('1.25')}, {'category': 'A', 'amount': Decimal('2.25')}, {'category': 'B', 'amount': Decimal('4.00')}]
nested result: {'A': '3.50'}
defaultdict result: {'A': '3.50', 'B': '4.00'}