Sets & Frozensets
Sets store unique hashable elements with fast membership tests. Frozensets are immutable sets you can use as dict keys or elements of other sets.
Search across all documentation pages
Sets store unique hashable elements with fast membership tests. Frozensets are immutable sets you can use as dict keys or elements of other sets.
seen: set[int] = set()
for value in [1, 2, 2, 3]:
if value not in seen:
seen.add(value)
a, b = {1, 2, 3}, {3, 4}
union = a | b
only_a = a - bWhen to reach for this:
def unique_preserve_order(items: list[str]) -> list[str]:
seen: set[str] = set()
result: list[str] = []
for item in items:
if item not in seen:
seen.add(item)
result.append(item)
return result
def jaccard(tags_a: set[str], tags_b: set[str]) -> float:
if not tags_a and not tags_b:
return 1.0
return len(tags_a & tags_b) / len(tags_a | tags_b)
def frozen_key(groups: list[frozenset[str]]) -> dict[frozenset[str], int]:
return {group: len(group) for group in groups}
if __name__ == "__main__":
print(unique_preserve_order(["a", "b", "a", "c"]))
print(jaccard({"py", "ml"}, {"py", "web"}))
print(frozen_key([frozenset({"a", "b"}), frozenset({"c"})]))What this demonstrates:
dict.fromkeys is not enough ordering control& and | for intersection and unionfrozenset as dict key for groupingsa <= b, a < b, a >= b for containment.{x for x in items if cond} builds sets directly.| Operator | Meaning |
|---|---|
| | union |
& | intersection |
- | difference |
^ | symmetric difference |
# empty set - not {}
empty = set()
# bulk add
tags.update(["a", "b", "c"])
# discard vs remove - discard ignores missing
tags.discard("missing"){} is empty dict - Use set() for empty set. Fix: set() or {0} placeholder only if intentional.set(s) before removing in loop.| Alternative | Use When | Don't Use When |
|---|---|---|
dict.fromkeys | Order-preserving unique keys | Need set algebra |
list + in | Very small n | Large membership checks |
bloom filter | Probabilistic huge scale | Need exact membership |
pandas.unique | Column dedupe in dataframes | Plain Python script |
set when order does not matter and membership is frequent. Order-preserving dedupe uses dict or manual loop.
Hashable set - dict keys, set elements, cache keys from frozenset of tags.
from functools import reduce; reduce(set.__and__, sets) or loop with acc &= s.
Same for sets - pick readable operator or method consistently in codebase.
Yes if all elements hashable and comparable for equality - but harms clarity; prefer homogeneous sets.
list(dict.fromkeys(items)) - fast idiomatic pattern.
Elements in either set but not both - diffing permission grants between environments.
{x for x in items if pred(x)} builds set directly without intermediate list.
Individual operations atomic in CPython but compound read-modify-write needs locks.
set.pop() removes arbitrary element - useful only when any element acceptable.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026