groupby groups runs, not keys¶
Level: 201 · for Python programmers, especially ones coming from SQL or ABAP
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The bullets below are the questions the finished page has to answer.
One line: itertools.groupby starts a new group every time the key changes, so unsorted input hands you the same key several times, and the group it gives you is a window onto the same iterator as the outer loop — advance the outer loop and the group you were holding is empty.
What the finished page has to answer¶
- The SQL intuition and why it is wrong here:
GROUP BYcollects a key from anywhere in the table,groupbybehaves likeuniq -con a stream, and an unsorted input gives the key'a', then'b', then'a'again. Measured. - Sort first, with the same key function, and why the stability of
sortedmakes the order inside each group predictable. - The shared iterator:
[(k, list(g)) for k, g in groupby(data)]works, andlist(groupby(data))gives every group empty, because by the time you read a group the outer iterator has moved past it. Measured, with An iterator is used up as the reason. - When you want whole-input grouping instead:
collections.defaultdict(list)andcollections.Counter, which read everything once and keep it. key=None, and grouping onstr.loweroroperator.itemgetteras the two usual keys.
See also¶
- An iterator is used up: why the group vanishes
- Sorting is not comparing: the key function, and what sorting strings actually orders by
itertools.groupby↗ in the Python docs, whose first paragraph says this and is not read