पाठ 9 / 25

Counter, defaultdict, OrderedDict and ChainMap

Use the collections module for common dictionary patterns.

Specialised dictionaries

The collections module provides dictionary variants for common patterns. Counter counts hashable items: Counter(words), most_common(k), arithmetic between counters (+, -, &, |) and update to add more counts; missing keys return 0. defaultdict(factory) creates a default value the first time a missing key is accessed, ideal for grouping (defaultdict(list)) and nested counters; be aware that merely reading a missing key inserts it. OrderedDict remembers order (as plain dicts now do) but adds move_to_end and popitem(last=False), which make it a convenient building block for LRU caches, and its equality comparison is order-sensitive. ChainMap searches several dictionaries in order without copying them, useful for layered configuration (command-line options over environment variables over defaults). Also useful: deque (next section) and namedtuple. For read-only views of a dict, use types.MappingProxyType. Choosing the right one replaces several lines of boilerplate and expresses intent clearly.

Grouping, counting and layered configuration

defaultdict, Counter, OrderedDict and ChainMap.

from collections import ChainMap, Counter, OrderedDict, defaultdict
import os

orders = [("Pune", "pen"), ("Delhi", "ink"), ("Pune", "ink"), ("Pune", "pen")]

items_by_city = defaultdict(list)
for city, sku in orders:
    items_by_city[city].append(sku)            # no need to check if the key exists
print(dict(items_by_city))                     # {'Pune': ['pen', 'ink', 'pen'], 'Delhi': ['ink']}

sku_counts = Counter(sku for _, sku in orders)
print(sku_counts.most_common(1))               # [('pen', 2)]
print(sku_counts["stapler"])                   # 0: missing keys count as zero

september = Counter(pen=10, ink=4)
october = Counter(pen=6, pad=3)
print(september + october)                     # Counter({'pen': 16, 'ink': 4, 'pad': 3})

recent = OrderedDict()
for page in ["home", "cart", "home", "checkout"]:
    recent[page] = True
    recent.move_to_end(page)                   # most recent at the end
print(list(recent))                            # ['cart', 'home', 'checkout']

defaults = {"theme": "light", "page_size": 20}
env = {k.lower(): v for k, v in os.environ.items() if k in {"THEME"}}
cli = {"page_size": 50}
config = ChainMap(cli, env, defaults)          # first mapping wins
print(config["page_size"], config["theme"])    # 50, and 'light' unless THEME is set

defaultdict reads create keys

if counts[key] > 0: on a defaultdict(int) inserts key with 0. Use key in counts or counts.get(key, 0) when you only want to look.

त्वरित जाँच: Which collections type returns 0 for missing keys and provides most_common()?

  • OrderedDict
  • ChainMap
  • Counter
  • deque
Answer

Counter — Counter is a dict subclass designed for counting.