Python > Advanced Python Concepts > Type Hinting > Syntax of Type Hints
Advanced Type Hinting: Generics and Union Types
This snippet demonstrates more advanced type hinting features, including using generics to specify the types of elements within collections and using Union to indicate that a variable can hold values of different types.
Code Example
This code shows the use of `List`, `Dict`, `Union`, and `Optional` from the `typing` module. * `List[Dict[str, Union[int, str]]]` indicates a list of dictionaries where keys are strings and values can be either integers or strings. * `Union[int, str]` allows a variable to hold either an integer or a string value. * `Optional[str]` means that the variable can either be a string or `None`, simplifying the usage of `Union[str, None]`.
from typing import List, Dict, Union, Optional
def process_data(data: List[Dict[str, Union[int, str]]]) -> List[str]:
"""Processes a list of dictionaries and returns a list of strings."""
results: List[str] = []
for item in data:
name = item.get("name")
value = item.get("value")
if isinstance(name, str) and isinstance(value, (int, str)):
results.append(f"{name}: {value}")
return results
my_data: List[Dict[str, Union[int, str]]] = [
{"name": "age", "value": 30},
{"name": "city", "value": "New York"},
{"name": "zip", "value": 10001}
]
print(process_data(my_data))
def greet_optional(name: Optional[str] = None) -> str:
if name:
return f"Hello, {name}!"
else:
return "Hello, guest!"
print(greet_optional())
print(greet_optional("Bob"))
Concepts Behind the Snippet
Generics and Union types enhance the expressiveness of type hints. Generics allow you to specify the types of elements within collections (e.g., the type of items in a list). Union types allow you to specify that a variable can hold a value of one of several different types. `Optional[T]` is shorthand for `Union[T, None]`.
Real-Life Use Case
Consider a function that can accept data from different sources, where each source provides data in a slightly different format. Union types can be used to specify the possible types of input data. Generics are useful when dealing with collections of data that are consistently typed, e.g., a list of user objects from a database.
Best Practices
Interview Tip
Be prepared to explain the difference between generics and Union types, and when each should be used. Understand the meaning of `Optional` and how it relates to `Union`.
When to Use Them
Use generics and Union types when you need to specify more complex type constraints than basic types can provide. These are important for creating robust and maintainable code.
Alternatives
Without generics and Union types, you would rely on `Any` type (which disables type checking) or create more complex type hierarchies. `Any` should be avoided where possible as it bypasses type checking.
Pros
Cons
FAQ
-
What is the difference between `Union` and `Any`?
`Union` specifies that a variable can hold one of a specific set of types, while `Any` means that the variable can hold a value of any type. `Any` effectively disables type checking for that variable, while `Union` still provides some type safety. -
When should I use `Optional` instead of `Union[T, None]`?
`Optional[T]` is a shorthand notation for `Union[T, None]`. Using `Optional[T]` is generally preferred for readability and conciseness when specifying that a variable can be either of type `T` or `None`.