Built-in & Collection Generics
Modern Python uses built-in collection generics (list[int]) and collections.abc abstract types to describe containers precisely - both for readers and for mypy/pyright.
Search across all documentation pages
Modern Python uses built-in collection generics (list[int]) and collections.abc abstract types to describe containers precisely - both for readers and for mypy/pyright.
from collections.abc import Iterable, Mapping, Sequence
def total_lengths(names: Sequence[str]) -> int:
return sum(len(n) for n in names)
def merge(base: Mapping[str, int], extra: Mapping[str, int]) -> dict[str, int]:
return {**base, **extra}When to reach for this:
from collections.abc import Callable, Iterable, Iterator, Mapping
def index_by(items: Iterable[dict], key: str) -> dict[str, dict]:
result: dict[str, dict] = {}
for item in items:
result[str(item[key])] = item
return result
def batch(iterator: Iterator[int], size: int) -> Iterable[list[int]]:
batch_items: list[int] = []
for value in iterator:
batch_items.append(value)
if len(batch_items) == size:
yield batch_items
batch_items = []
if batch_items:
yield batch_items
def apply_all(fns: Mapping[str, Callable[[], None]]) -> None:
for fn in fns.values():
fn()
if __name__ == "__main__":
rows = [{"id": "1", "name": "Ada"}, {"id": "2", "name": "Linus"}]
print(index_by(rows, "id"))What this demonstrates:
Iterable accepts list, generator, and custom iteratorsIterator is single-pass - checker warns if reused incorrectly in strict modeMapping documents read-only dict-like without mutation methodsCallable[[], None] types zero-arg side-effect functionslist[int]).list[Dog] not list[Animal]).collections.abc in annotations (3.9+).dict[str, list[int]] for adjacency lists.| Accept | When |
|---|---|
Sequence | Indexing + len needed |
Iterable | Single forward pass |
Mapping | Key lookup read-only |
MutableMapping | Needs setitem/delitem |
# invariant list - use Sequence for read-only param
def print_all(items: Sequence[str]) -> None:
for item in items:
print(item)typing.List deprecated style on 3.9+. Fix: list[int].dict[str, int] not compatible with dict[str, float] in strict variance. Fix: Use values union or Mapping.dict[str, Any] loses safety. Fix: TypedDict or Pydantic model.tuple[int, ...] for homogeneous variable length vs fixed tuple[int, str].| Alternative | Use When | Don't Use When |
|---|---|---|
TypedDict | Known string keys | Dynamic keys only |
| Pydantic model | Validated nested JSON | Inner numeric kernel |
TypeAlias | Complex nested alias | Single simple list[int] |
numpy.ndarray | Numeric tensors | General Python containers |
Parameter type Sequence when you only read/index; list when caller must pass mutable list specifically.
Iterable produces iterator via iter(). Iterator is exhausted after one pass.
Mapping signals read-only API; dict when function mutates or returns concrete dict.
set[str] for homogeneous sets - invariant like list.
frozenset[str] same as set for typing purposes.
Iterator[T] or Iterable[T] - Iterator stricter single-pass semantics.
bytes for binary; memoryview rarely in public APIs - use Buffer protocol types in advanced typing.
dict[str, object] loose; TypedDict or models for real safety.
collections.abc.Callable preferred in 3.9+ annotations.
Sequence[T] - no append in type contract though runtime list still mutable.
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