pysnippets.lists.difference_by
List difference by a key
difference_by(a: Iterable[T], b: Iterable[T], key: Callable[[T], K]) -> list[T]
Keep the items of one list whose key doesn't appear in another, preserving order.
set(a) - set(b) loses order and needs hashable items. This compares on a key instead, so it works for dicts and objects.
difference_by.py✓ ruff · mypy --strict
from collections.abc import Callable, Hashable, Iterable
from typing import TypeVar
T = TypeVar("T")
K = TypeVar("K", bound=Hashable)
def difference_by(a: Iterable[T], b: Iterable[T], key: Callable[[T], K]) -> list[T]:
"""Return the items of ``a`` whose ``key`` matches no item of ``b``."""
seen = {key(item) for item in b}
return [item for item in a if key(item) not in seen]- a set of b's keys makes each lookup O(1)
examples✓ 3 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> from math import floorpassed on Python 3.11 to 3.14: >>> difference_by([2.1, 1.2], [2.3, 3.4], floor)[1.2]passed on Python 3.11 to 3.14: >>> difference_by([{"x": 2}, {"x": 1}], [{"x": 1}], lambda d: d["x"])[{'x': 2}]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
- The keys of
bgo into a set, so each lookup is O(1). - Items of
akeep their order and their duplicates.
Complexity: O(n + m) time, O(m) space
- 3.11✓passes
- 3.12✓passes
- 3.13✓passes
- 3.14✓passes
Import
from pysnippets.lists.difference_by import difference_byNo dependencies: copy difference_by.py into your project, or clone the repo.Adapted from difference-by in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Typed; fixed the example's invalid result syntax. Suggest an edit.