Explain Codes LogoExplain Codes Logo

Type hinting a collection of a specified type

python
type-hinting
python-3.9
mypy
Nikita BarsukovbyNikita Barsukov·Mar 8, 2025
TLDR

For type hinting in Python, typing module provides List, Set, Tuple, Dict for hinting collections. Define the element types using square brackets. List[T] for lists, Set[T] for sets, Tuple[T1, T2, ...] for tuples, and Dict[K, V] for dictionaries with specified key and value types.

from typing import List, Set, Tuple, Dict # just some random scores.. John was grounded. my_int_list: List[int] = [1, 2, 3] my_str_set: Set[str] = {"hello", "world"} # tuple's got a mixed bag of types my_mixed_tuple: Tuple[int, str] = (1, "A") # You're older than you've ever been and now you're even older... my_dict: Dict[str, int] = {"age": 30, "score": 100}

Using List[int], Set[str], etc. provides painless type detection and sklearn-level model performance in terms of self-documentation.

Python 3.9+: Directly hint with standard types

Type hinting's been made as easy as liking a cat video. In Python 3.9 and onwards, you can use standard collection types (list, dict, etc.) directly for generic types. This change, brought by PEP 585, eliminates the need to import typing — type checkers like mypy will have no issues with these.

# numbers on the wall, and yes they're all prime my_int_list: list[int] = [2, 3, 5, 7, 11] # When age == score, you've unlocked the meaning of life my_dict: dict[str, int] = {"age": 42, "score": 42}

For dragons older than Python 3.5, stick to typing module:

from typing import List, Dict # Not so random, it's Fibonacci! my_int_list: List[int] = [0, 1, 1, 2, 3, 5] # Python programmers never die... my_dict: Dict[str, int] = {"age": 30, "score": 100}

Master of puppets: Nested type hints

Type hinting isn't afraid of complex things (like fusion cuisine). For nested types within collections, nest the type hints:

from typing import List, Dict # Who thought arrays could do the inception thing. my_nested_list: List[Dict[str, list[int]]] = [ {"scores": [98, 85, 100]}, # each score > no. of Taylor Swift Grammy wins {"scores": [75, 90]} # someone needs a tutor! ]

Use dict with str keys and list[int] values for deeper level type hinting.

The future is now: Postponed evaluation

In the times of the Python 3.7- era, type hints could cause nasty circular import issues. PEP 563 got the ball rolling to sort this out, allowing postponed evaluation of type annotations. This magic incantation—from __future__ import annotations—means you can now refer to a class within its own definition:

from __future__ import annotations class Node: # Node meets recursion, github's latest love story def add_child(self, child: Node): pass # implementation

IDE + Type Hinting = Code that reads like a book

How can a str become an int? Ask Parseghian!

Good news is that type hints are not just for aesthetes. They make your code as readable as the latest HBR's Must Reads, and if you're using an IDE like PyCharm, you may even get features like:

  • Types on tips: Code completion
  • Knowing what to pass: Parameter info
  • Nipping errors in the bud: Error detection
  • Changing names is safe: Refactoring aids

With mypy, you also get static type checking, saving you tears at runtime.

More power to you: Advanced typing constructs

Stepping up your type game? Throw in TypeVar, NewType, Generic, and other powerful constructs from typing to define custom generics, enforce type constraints, or even create distinct types:

from typing import TypeVar, NewType, List T = TypeVar('T') UserId = NewType('UserId', int) # Don't mix user IDs with any other ints. They're sorta special. def handle_users(user_ids: List[UserId]): pass # implementation

References