The Dict Comparator
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
- Asked in
- Circana
Problem
A service's live config has drifted from the baseline it shipped with, and on-call needs to see exactly what moved. Given the current config current and the baseline, return the entries from current whose value no longer matches the baseline, keyed to their current values.
Two dictionaries. Subtle differences.
Example 1
Input:
current = {"host":"web-01","port":8080,"timeout":30}, baseline = {"host":"web-01","port":9090,"user":"root"}Output:
{"port":8080,"timeout":30}Example 2
Input:
current = {"region":"us-east","replicas":3}, baseline = {"region":"us-east","replicas":3}Output:
{}Worked solution and explanation
What this problem really is
Strip the config-drift framing and this is a keyed set difference with a value check: return the entries of current that the baseline does not agree on. The whole problem lives in one word, 'differs'. A key with a new value differs, sure, but so does a key the baseline has never seen. Candidates who model this as 'shared keys with unequal values' quietly drop every freshly added key, which is precisely the drift you were asked to catch. And the ones who write baseline[key] instead of a membership check hand you a KeyError on the first new key.
Two ways a key drifts
A key belongs in the diff for one of two reasons: the baseline never had it, or the baseline had it with a different value. The elegant part is that a single condition catches both, and the order of the two tests is what keeps you from crashing.
Step 1: Walk the current config, not the baseline
Iterate current only, pulling each key and value together with current.items(). Every key you might report has to live in current, so starting from the baseline instantly risks leaking keys that were removed rather than added.
Step 2: Fold 'missing' and 'changed' into one test
A key drifts if the baseline never had it OR the baseline had a different value. Check membership first (key not in baseline); the or short-circuits, so you never index a key that isn't there.
Step 3: Take the value from the current side
When a key qualifies, store value, the value you unpacked from current. The report answers 'what is it now', so the baseline value never enters the output.
The solution
def dict_diff(current: dict, baseline: dict) -> dict:
drift = {}
for key, value in current.items():
if key not in baseline or baseline[key] != value:
drift[key] = value
return driftMissing and changed keys are handled by a single condition; no sorting, no second pass.
- Shared keys only (wrong)
{k: current[k] for k in current.keys() & baseline.keys() if current[k] != baseline[k]}compares only keys in both, so every freshly added key silently vanishes from the diff.- Iterate current, guard membership (right)
- Loop
current.items()and include a key whenkey not in baseline or baseline[key] != value. New keys and changed keys both land in the result.
Common follow-up questions
- How would you produce a symmetric diff that also reports keys removed from the baseline? (Tests combining a current-vs-baseline diff with a baseline-vs-current diff.)
- What if the values are themselves nested dicts? (Tests recursive deep comparison.)
- How would you report what changed, old value versus new? (Tests returning a (baseline, current) pair rather than just the current value.)