Understanding the Difference Between `List` and `list` in Python Type Hinting

What will you learn?

In this comprehensive guide, you will delve into the distinction between List and list when it comes to type hinting in Python. By exploring their differences, historical context, compatibility considerations, and practical usage scenarios, you will gain a deeper understanding of how to effectively utilize these type hints in your Python projects.

Introduction to the Problem and Solution

When writing Python code, particularly in versions 3.5 through 3.8, developers encounter two similar yet distinct approaches for hinting at list types: List, provided by the typing module, and the built-in list. This can create confusion for programmers at all levels of expertise. To address this confusion, we will unravel the significance of each approach, their evolution within Python’s type annotation landscape, compatibility nuances across different Python versions, and offer guidance on when to employ each method effectively.

Our solution involves dissecting the background behind both List and list within Python’s journey towards more explicit type annotations. Through illustrative code examples showcasing the usage of each approach and discussing best practices aligned with Python’s current recommendations on type hinting, you will be equipped to navigate the realm of type annotations with confidence.


from typing import List

# Using List from typing module (Python 3.5 - 3.8)
def process_items(items: List[int]) -> None:
    for item in items:

# Using list as of Python 3.9+
def process_elements(elements: list[int]) -> None:
    for element in elements:

# Copyright PHD


The primary distinction between List (uppercase) from the typing module and lowercase list lies in version compatibility:

  • Using List:

    • In versions prior to Python 3.9, specifying a function parameter as a list containing elements of a specific type involved using List [int].
    • It necessitated importing List from the typing module.
  • Using list:

    • With Python 3.9+, developers could directly use built-in generics by employing lowercase list [int], eliminating the need for an import statement.
    • This change enhances code readability while maintaining precise annotation.

The introduction of PEP 585 aimed to simplify annotations by leveraging native collection types (dict, set, etc.), including lower-case ‘list’.

  1. What is PEP 585?

  2. PEP stands for Python Enhancement Proposal´┐Ża document proposing changes or providing information to members of the Python community.

  3. Why was there a shift from using ‘List’ to ‘list’?

  4. The transition aimed at enhancing readability and reducing verbosity by embracing built-in generics instead of relying solely on external modules like typing.

  5. Can I still use ‘List’ in newer versions post-Python 3.9?

  6. Yes, but it is advisable to adopt the newer convention (list) as it aligns with future directions emphasized by core developers.

  7. How do I specify an empty list as a default argument using type hints?

  8. You can annotate it like this:

  9. def func(a: list[int] = []) -> None:
  10. # Copyright PHD
  11. However, remember that mutable defaults can lead to issues; hence initializing inside the function body after checking if it’s None is recommended.

  12. Is there any performance difference between ‘List’ and ‘list’?

  13. No significant runtime performance differences exist since these annotations are removed during bytecode compilation´┐Żserving purely informational purposes.


Understanding why conventions around seemingly simple aspects like indicating “this should contain lists” evolve over time is crucial for writing clean and maintainable code amidst evolving language standards. Staying updated through official resources helps navigate shifts smoothly while ensuring your skills remain relevant in the ever-changing landscape of software development.

Leave a Comment