python 33 lines · 7 steps

Two ways to dedupe while keeping order

Stream items through a set to keep first occurrences, or through an OrderedDict to keep the last.

Explained by highlit
1from collections import OrderedDict
2from typing import Callable, Hashable, Iterable, Iterator, TypeVar
3 
4T = TypeVar("T")
5 
6 
7def dedupe(
8 items: Iterable[T],
9 key: Callable[[T], Hashable] | None = None,
10) -> Iterator[T]:
11 seen: set[Hashable] = set()
12 extract = key or (lambda item: item)
13 
14 for item in items:
15 marker = extract(item)
16 if marker in seen:
17 continue
18 seen.add(marker)
19 yield item
20 
21 
22def dedupe_last_wins(
23 items: Iterable[T],
24 key: Callable[[T], Hashable],
25) -> list[T]:
26 collapsed: OrderedDict[Hashable, T] = OrderedDict()
27 
28 for item in items:
29 marker = key(item)
30 collapsed.pop(marker, None)
31 collapsed[marker] = item
32 
33 return list(collapsed.values())
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1A set of computed keys lets you dedupe by identity while still yielding the original objects.
  2. 2Generators make first-wins deduplication lazy, so you never materialize the full input.
  3. 3Popping then re-inserting into an OrderedDict moves a key to the end, giving clean last-wins ordering.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Two ways to dedupe while keeping order — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code