pythonlistpython-typing

How would you type hint Dict in Python with constant form but multiple types?


I want to type hint the return object of some_func function, which is always the same format. Is this correct?

from typing import List, Dict


def some_func() -> List[Dict[str, int, str, List[CustomObject]]]:
    my_list = [
               {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
               {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
               ]
    return my_list

Solution

  • one way of correctly type hinting would look like this:

    from typing import List, Dict, Union
    
    def some_func() -> List[Dict[str, Union[int, List[CustomObject]]]]:
        my_list = [
                   {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
                   {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
                   {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
                   ]
        return my_list
    

    for a brief explanation, when type annotating a dict, you can only have two arguments, the first being the type of any given key, and the second, the type of any given value. since keys are always strings, we keep Dict[str, and our keys can be either an integer, or of type CustomObject, to represent different possibilities in type annotations we use Union, and so in the end we get:

    Dict[str, Union[int, List[CustomObject]]
    

    for some additional notes, in python 3.9 or above you may replace Dict imported from typing, with the builtin dict, and in python 3.10 or above, unions can be represented as type | type, and you can replace List with the builtin list

    for a cleaner result you may want to use a typedDict, the overall result would be:

    from typing import TypedDict
    
    class customDict(TypedDict):
        ID: int
        cargo: list[CustomObject]
    
    def some_func() -> list[customDict]:
        my_list = [
                   {"ID": 1, "cargo": [CustomObject(), CustomObject()]},
                   {"ID": 2, "cargo": [CustomObject(), CustomObject()]},
                   {"ID": 2, "cargo": [CustomObject(), CustomObject()]}
                   ]
        return my_list
    

    each property of the typed dict represents a key of the dicts in my_list, and the following reprents the type of value related to the key