[*]
I like @b4hand’s examples, and indeed I have used in the past ChainMap-like structures (but not ChainMap itself) for the two purposes he mentions: multi-layered configuration overrides, and variable stack/scope emulation.
I’d like to point out two other motivations/advantages/differences of ChainMap, compared to using a dict-update loop, thus only storing the “final” version”:
-
More information: since a ChainMap structure is “layered”, it supports answering question like: Am I getting the “default” value, or an overridden one? What is the original (“default”) value? At what level did the value get overridden (borrowing @b4hand’s config example: user-config or command-line-overrides)? Using a simple dict, the information needed for answering these questions is already lost.
-
Speed tradeoff: suppose you have
Nlayers and at mostMkeys in each, constructing a ChainMap takesO(N)and each lookupO(N)worst-case[*], while construction of a dict using an update-loop takesO(NM)and each lookupO(1). This means that if you construct often and only perform a few lookups each time, or ifMis big, ChainMap’s lazy-construction approach works in your favor.
[*] The analysis in (2) assumes dict-access is O(1), when in fact it is O(1) on average, and O(M) worst case. See more details here.