5

I want to specify a type hint for a function can receive either a list of strs or a list of ints. Is there a way to do this using Python? Something like:

from typing import List

def my_function(list_arg: List[str|int]):

    ...
    ...
0

2 Answers 2

4

Union is intended precisely for this situation. It creates a new type that can be any of the types you specify:

from typing import Union, List
def my_function(list_arg: Union[List[str], List[int]]) -> None: ...

If you use it often, make a type alias:

MyList = Union[List[str], List[int]]
def my_function(list_arg: MyList) -> None: ...

I wouldn't recommend using a generic function as @user6269244 answer suggests unless you need it for some specific reason. Although T = TypeVar('T', int, str) will work in a simple case, it will be more restrictive.

For example, suppose you have something like this:

def apply_my_function(list_of_lists: List[MyList]) -> None:
  # each item in list_of_lists is either a List[int] or List[str]
  for arg in list_of_lists:
    my_function(arg)

In this code, you have no chioce: you need a Union (List[List[T]] won't let you store both a list of int and a list of str because T can't switch between str and int in the same expression).

But since you use Union in the code that calls my_function, you'll also have to use Union in the signature of my_function itself.

In addition, generics increase the complexity of the types, and at some point you will run into the limitations of the type system. So it's better to reserve generics for cases where you really need them, for example if you want the return type of my_function to depend on the argument type:

T = TypeVar("T", int, str)

# this can't be achieved with Union:
def my_function(list_arg: List[T]) -> T: ...
Sign up to request clarification or add additional context in comments.

1 Comment

I guess this is more complete so I'm marking it correct for others but thanks @user6269244 - it solved the problem well enough for me before!
-1
from typing import TypeVar, List

T = TypeVar("T", int, str)

def my_function(list_arg: List[T]):
...

1 Comment

This is actually correct, but only if there's a need for a generic function, which is not obvious from the question. For example, if you want to use T in the types of variables inside my_function or in the return type of my_function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.