在Python中,如何指定参数是所有元素类型相同的列表?

In Python, how to specify argument is a list where all elements have the same type?

快速提问...

我正在尝试做这样的事情:

from typing import List


def reverse_list(original: List) -> List:
    return original[::-1]

如果我传入这样的东西,我想得到一个警告:[1, 3, "a", 10],因为并非所有元素都具有相同的类型。

我愿意接受 ["c", "a", "b"][1, 8, 2]——并让 Python 知道 return 值将是字符串列表或整数列表。

这可行吗?我感觉不是。

谢谢!

这样试试。遍历列表中的每个元素,如果它不是整数则引发错误。

from typing import List

def reverse_list(original: List) -> List:
    for element in original:
        if not isinstance(element, int):
            raise TypeError("Element of the list: " + element + " is not an integer.")
    return original[::-1]

您需要自己进行测试

from typing import List
import warnings

def sameType(a, b):
 return type(a) == type(b)

def allSameType(aList):
 allZip = zip(aList, aList[1:])
 return all([sameType(a,b) for a,b in allZip])

def reverse_list(original: List) -> List:
    if not allSameType(original):
        warnings.warn('Not all the items in your list are the same type')
    return original[::-1]

如果您认为继承的 类 与他们的祖先是同一类型,请将 type(a) == type(b) 更改为 isinstance(a, b)

这就是我想到的

def check_if_mix(list_: List):
    first_type = type(list_[0])
    return any(not isinstance(i, first_type) for i in list_)

check_if_mix([1,2,3])
>>>False

check_if_mix([1,2,"a"])
>>>True

因此,如果您想在出现混合类型时收到警告,最简单的方法是在反转列表之前检查一下:

def reverse_list(original: List) -> List:
    if check_if_mix(original):
        print('WARNING: list contains mixed types')
    return original[::-1]

如果您使用像 mypy 这样的静态类型检查器来检查您的程序,正确的做法是让您的函数成为 generic function:

from typing import List, TypeVar

T = TypeVar('T')

def reverse_list(original: List[T]) -> List[T]:
    return original[::-1]

TypeVar 是一个 "placeholder"——类型检查器会理解如果我们将一个 List[str] 传入这个函数,那么 T 必须是类型 str。因此,在完成替换后,它会得出结论输出类型也必须是 List[str]

请注意,此解决方案比其他解决方案更有效,因为根本没有运行时检查发生——Python 解释器完全忽略类型提示。静态类型检查器将改为验证程序的正确性。

(这也可能是一个缺点——在类型检查开始成为防止错误的有效方法之前,您需要向程序的大部分添加准确的类型提示,而这样做并不总是可行。)