Group category records after sorting them
Group category records after sorting them
By Batu.
itertools.groupby() creates a new group whenever its key changes; it does not search the rest of an iterable for matching keys. The input records below alternate between violet and amber, so grouping that original order would create four short runs. Sorting with key=itemgetter(0) first makes equal category values adjacent. groupby() then yields exactly one amber group and one violet group.
Each group returned by groupby() is an iterator sharing the same underlying input. The list comprehension immediately consumes grouped into a list of labels before the outer loop requests the next category. That timing matters: saving those group iterators and consuming them later can leave earlier ones empty because the shared source has moved on.
The result preserves the original label order within each category because Python sorting is stable: archive stays before label, and check stays before ship. Sorting also means this recipe needs a finite, materializable input and has an ordering cost; it is not a whole-stream aggregation technique for an unbounded feed. For totals across arbitrary arrival order, use a dictionary-based accumulator instead. Categories must have comparable sort keys, or sorted() can fail.
The Python groupby() documentation explains its consecutive-key grouping model.
AI assistance was used in preparing this Batu article.
from itertools import groupby
from operator import itemgetter
records = [
("violet", "check"),
("amber", "archive"),
("violet", "ship"),
("amber", "label"),
]
ordered = sorted(records, key=itemgetter(0))
groups = [
(category, [label for _, label in grouped])
for category, grouped in groupby(ordered, key=itemgetter(0))
]
assert groups == [("amber", ["archive", "label"]), ("violet", ["check", "ship"])]
print(groups)
Expected stdout:
[('amber', ['archive', 'label']), ('violet', ['check', 'ship'])]
Comments
Post a Comment