pysnippets.dicts.collect_dictionary
Invert a dictionary, keeping every key
collect_dictionary(d: Mapping[K, V]) -> dict[V, list[K]]
Invert a dict so each value maps to the list of keys that had it.
Who is 10 years old? Inverting {name: age} with a plain comprehension keeps only one name per age. This keeps all of them.
collect_dictionary.py✓ ruff · mypy --strict
from collections import defaultdict
from collections.abc import Hashable, Mapping
from typing import TypeVar
K = TypeVar("K")
V = TypeVar("V", bound=Hashable)
def collect_dictionary(d: Mapping[K, V]) -> dict[V, list[K]]:
"""Invert ``d``, collecting every key that shares a value into a list."""
inverted: defaultdict[V, list[K]] = defaultdict(list)
for key, value in d.items():
inverted[value].append(key)
return dict(inverted)- keys stay in d's order inside each list
examples✓ 2 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> collect_dictionary({"Peter": 10, "Isabel": 10, "Anna": 9}){10: ['Peter', 'Isabel'], 9: ['Anna']}passed on Python 3.11 to 3.14: >>> collect_dictionary({}){}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).
python 3.14 · in your browser
Loading Python 3.14 in your browser (≈7 MB, cached after the first time)…
Tab inserts four spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the examples.
How it works
defaultdict(list)starts an empty list for each new value.- Keys keep the dict’s order inside each list.
- It’s
group_byapplied to a dict’s items.
Complexity: O(n) time, O(n) space
- 3.11✓passes
- 3.12✓passes
- 3.13✓passes
- 3.14✓passes
Import
from pysnippets.dicts.collect_dictionary import collect_dictionaryNo dependencies: copy collect_dictionary.py into your project, or clone the repo.Adapted from collect-dictionary in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Typed; returns a plain dict. Suggest an edit.