正确输入整数列表

问题描述 投票:0回答:3

考虑文件 x.py 中的以下代码

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]"

所以我将 x.py 更改为以下内容:

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"

那么我如何正确注释代码以使 mypy 不抱怨(当然,两个版本在运行时的行为完全相同并按预期工作)?

脚本的“做某事”部分需要列表末尾的“无”元素(与问题无关,因此此处未显示)

编辑(19/09/2022)开始 根据要求,这是有效的代码:

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

编辑结束

python python-typing mypy
3个回答
1
投票

您可以通过查看实际代码在做什么来解决这个问题:

None
,因为切片的端点意味着
len(string)
,所以如果您将其改为,那么您的列表可以保留
List[int]

from typing import List

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))
    indices.sort()

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

这就过去了

mypy --strict

示例输出,只是为了确定:

>>> parse_job_attributes('re_foobar', ['foo', 're'])
['re_', 'foobar']

同样,由于您要从

range(len(indices) - 1)
中的 len 中减去 1,因此甚至不需要检查
if len(sorted_indices) > 0
;您可以无条件追加,并且范围仍为空。这开辟了一些其他解决方案,例如:

sorted_indices: List[Optional[int]] = [*sorted(indices), None]

附注请注意,整个答案基于“做某事”部分,您认为这并不重要。我提出这个问题并不是为了让您感到羞耻或任何其他事情,而是为了强调提供工作代码以避免 XY 问题


1
投票

不要将排序后的列表分配回原始变量

my_list
,而是将其分配给一个新变量,mypy 将允许该变量保存不同的类型。

my_list: List[int] = list()
for i in range(7):
    my_list.append(i)
# change here
sorted_list: List[Any] = sorted(my_list)
if len(sorted_list) > 0:
    sorted_list.append(None)

1
投票

基于crunker99的答案正确指出了新列表,我能够想出满足mypy的这段代码:

from typing import List, Optional

my_list: List[int] = list()
for i in range(7):
    my_list.append(i)
my_sorted_list: List[Optional[int]] = list(sorted(my_list))
if (len(my_sorted_list) > 0):
    my_sorted_list.append(None)
# do something with my_sorted_list
© www.soinside.com 2019 - 2024. All rights reserved.