You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含Optional[int]的列表正确注解类型以通过mypy检查

问题:为包含None的列表正确添加类型注解以通过mypy检查

初始代码与报错

最初编写的代码如下:

from typing import List, Optional

my_list: List[Optional[int]] = list()
for i in range(7):
    my_list.append(i)
my_list = sorted(my_list)
if (len(my_list) > 0):
    my_list.append(None)
# do something with my_list

执行mypy x.py后触发类型检查错误:

x.py:6: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "Optional[int]"

原因是Optional[int]包含None类型,而None无法与整数进行大小比较,不符合sorted对可比较元素的要求。

修改后的代码与新报错

将列表类型改为List[int]后:

from typing import List

my_list: List[int] = list()
for i in range(7):
    my_list.append(i)
my_list = sorted(my_list)
if (len(my_list) > 0):
    my_list.append(None)
# do something with my_list

再次执行mypy x.py又出现新错误:

x.py:8: error: Argument 1 to "append" of "list" has incompatible type "None"; expected "int"

此时列表被标注为仅允许整数元素,无法添加None。

生产环境代码

实际生产中的业务代码如下:

from typing import List, Optional

def parse_job_attributes(string: str, tokens: List[str]) -> List[str]:
    indices = []
    for token in tokens:
        if token in string.lower():
            indices.append(string.lower().index(token))
    sorted_indices: List[Optional[int]] = list(sorted(indices))

    # indices = sorted(indices)
    if len(sorted_indices) > 0:
        sorted_indices.append(None)
    parts = [string[sorted_indices[i]:sorted_indices[i + 1]] for i in range(len(sorted_indices) - 1)]
    return parts

解决方案

方法1:拆分列表处理阶段,先排序纯整数列表再转换类型

先维护一个纯整数列表完成排序操作,再将其转换为允许None的列表类型,最后添加None元素:

from typing import List, Optional

my_list: List[int] = list()
for i in range(7):
    my_list.append(i)
# 对纯整数列表排序,无类型检查问题
sorted_int_list = sorted(my_list)
# 转换为允许包含None的列表类型
my_list_with_none: List[Optional[int]] = sorted_int_list
if len(my_list_with_none) > 0:
    my_list_with_none.append(None)
# do something with my_list_with_none

对应生产代码的修改:

from typing import List, Optional

def parse_job_attributes(string: str, tokens: List[str]) -> List[str]:
    indices = []
    for token in tokens:
        if token in string.lower():
            indices.append(string.lower().index(token))
    # 先排序纯整数列表
    sorted_indices_int: List[int] = sorted(indices)
    # 转换为允许包含None的类型
    sorted_indices: List[Optional[int]] = sorted_indices_int
    if len(sorted_indices) > 0:
        sorted_indices.append(None)
    parts = [string[sorted_indices[i]:sorted_indices[i + 1]] for i in range(len(sorted_indices) - 1)]
    return parts

方法2:使用类型断言跳过检查

如果能确定排序阶段的列表实际没有None元素,可以用cast告诉mypy排序后的列表类型:

from typing import List, Optional, cast

my_list: List[Optional[int]] = list()
for i in range(7):
    my_list.append(i)
# 断言排序后的列表仍为List[Optional[int]](因原列表此时无None)
my_list = cast(List[Optional[int]], sorted(my_list))
if len(my_list) > 0:
    my_list.append(None)
# do something with my_list

生产代码中对应修改:

from typing import List, Optional, cast

def parse_job_attributes(string: str, tokens: List[str]) -> List[str]:
    indices = []
    for token in tokens:
        if token in string.lower():
            indices.append(string.lower().index(token))
    sorted_indices: List[Optional[int]] = cast(List[Optional[int]], sorted(indices))
    if len(sorted_indices) > 0:
        sorted_indices.append(None)
    parts = [string[sorted_indices[i]:sorted_indices[i + 1]] for i in range(len(sorted_indices) - 1)]
    return parts

核心逻辑说明

问题的本质是sorted要求元素必须支持大小比较,而None无法与整数比较,因此不能直接对List[Optional[int]]排序。解决思路要么先处理纯整数列表的排序,再转换为允许None的类型,要么用类型断言明确告知mypy当前列表的实际元素类型。

内容的提问来源于stack exchange,提问作者user2606240

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:15:32