script_10.py - List Grouping
Code
See script_10.py for full code.
Explanation
Line 8: from collections import defaultdict
- defaultdict is dict subclass
- Provides default value for missing keys
Line 9: from itertools import groupby
- groupby() groups consecutive elements
Line 10: from operator import itemgetter
- itemgetter() creates function to extract item
Line 24: grouped_manual = defaultdict(list)
- Creates defaultdict with list as default factory
- Accessing missing key automatically creates empty list
- Type: defaultdict, behaves like dict
Line 26: grouped_manual[log["level"]].append(log)
- If key doesn't exist, creates empty list automatically
- Then appends to that list
- No need to check if key exists first
Line 28: for level, entries in grouped_manual.items():
- .items() returns key-value pairs
- entries is a list (the grouped logs)
Line 36: sorted_logs = sorted(logs, key=itemgetter("level"))
- itemgetter("level") creates function equivalent to lambda x: x["level"]
- More efficient than lambda
- Sorts by the "level" key
Line 37: for level, group in groupby(sorted_logs, key=itemgetter("level")):
- groupby() groups consecutive equal elements
- Requires sorted input (groups only consecutive items)
- Returns iterator of (key, group) tuples
- group is iterator (must convert to list)
Line 38: entries = list(group)
- Converts iterator to list
- Iterator can only be consumed once
Line 49: region_totals = defaultdict(lambda: {"total": 0, "count": 0})
- Lambda creates default dict with two keys
- Each missing region gets own dict with total and count
- Useful for aggregating multiple values