Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python type annotation for arbitrary list?

I would like to annotate an argument of a function to indicate that a list is expected as argument. However I would like to keep the base type of the list unspecified. Is there a way to do this? Ie use a placeholder like below?

def my_func(li: List[any])

edit is it possible to use a template:

Ie something like:

def union(li: List[List[T]])-> List[T]: 
like image 340
gen Avatar asked Nov 20 '25 21:11

gen


1 Answers

However I would like to keep the base type of the list unspecified. Is there a way to do this? Ie use a placeholder like below?

def my_func(li: List[any])

Yes. But you want Any:

Special type indicating an unconstrained type.

  • Every type is compatible with Any.
  • Any is compatible with every type.

is it possible to use a template:

Ie something like:

def union(li: List[List[T]])-> List[T]: 

Yes. Although these are called generics, not templates (because they're not actually something like C++ templates that provide a Turing-complete compile-time language, they're just simple generic types.

The only problem is that generic types require type variables, and there's no builtin type variable named T. But it's easy enough to create one, as shown in the docs, and of course T is the conventional "first generic parameter" typevar:

T = TypeVar('T')

… and then you can use it:

def union(li: List[List[T]])-> List[T]: 

If you already know C++ templates or Haskell parameterized types or Java generics or whatever, it's tempting to just jump in and start writing Python type annotations assuming you can guess what they mean. But really, you need to read at least the first few sections of the docs, or PEP 483 and the various other linked PEPs. Otherwise, you're going to guess all kinds of things wrong (not just what Any is called and how to declare TypeVars, but also probably what the parameters of Tuple are, how covariance works, which generic types are structurally checked vs. nominally, etc..


While we're at it, unless you really need the input to be a List, you probably want Sequence[Sequence[T]] or Iterable[Sequence[T]] or similar.

You can find all the details in Classes, functions, and decorators, but in general, anything from collections.abc that seems like it ought to have a generic counterpart in typing does.

like image 103
abarnert Avatar answered Nov 22 '25 12:11

abarnert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!