fluttersmith/py-snippetsGitHub ↗

Group items by a key

Bucket items into lists keyed by a function, keeping the original order inside each group.

Lists#groupingO(n) time✓ 4 examples pass on 3.11–3.14

Group words by length, orders by customer, files by extension: one function covers all of them.

group_by.py✓ ruff · mypy --strict
from collections import defaultdict
from collections.abc import Callable, Hashable, Iterable
from typing import TypeVar

T = TypeVar("T")
K = TypeVar("K", bound=Hashable)


def group_by(items: Iterable[T], key: Callable[[T], K]) -> dict[K, list[T]]:
    """Group ``items`` into lists by the result of ``key``, keeping their order."""
    groups: defaultdict[K, list[T]] = defaultdict(list)
    for item in items:
        groups[key(item)].append(item)
    return dict(groups)
  1. a plain dict, so a missing key raises instead of inserting
examples✓ 4 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> from math import floorpassed on Python 3.11 to 3.14: >>> group_by([6.1, 4.2, 6.3], floor){6: [6.1, 6.3], 4: [4.2]}passed on Python 3.11 to 3.14: >>> group_by(["one", "two", "three"], len){3: ['one', 'two'], 5: ['three']}passed on Python 3.11 to 3.14: >>> group_by([], len){}
Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).

How it works

  • defaultdict(list) creates each group’s list the first time its key appears.
  • Converting back to a plain dict means a later lookup of a missing key raises, instead of silently adding an empty group.
  • Groups appear in the order their first item was seen.

Complexity: O(n) time, O(n) space

Importfrom pysnippets.lists.group_by import group_byNo dependencies: copy group_by.py into your project, or clone the repo.

Adapted from group-by in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Typed with generic keys; prose rewritten. Suggest an edit.