向接受任何可迭代和 returns 压缩值的函数添加类型提示

Add type hints to function that accepts any iterable and returns zipped values

我有以下工作代码可以解决 Advent of Code 2021 day 1 (requires Python 3.10 due to itertools.pairwise),但我对如何正确添加类型提示感到困惑。

from itertools import pairwise, tee
from typing import Iterator, TypeVar, Tuple, Generator

_T_co = TypeVar("_T_co", covariant=True)

def tripletwise(iterable: Iterator[_T_co]) -> zip[Tuple[_T_co, _T_co, _T_co]]:
    """tripletwise('ABCDEFG') --> ABC BCD CDE DEF EFG"""
    a, b, c = tee(iterable, 3)
    next(b, None)
    next(c, None)
    next(c, None)
    return zip(a, b, c)


def sonar_sweep(sea_floor_depths: Generator[int, None, None], part: int = 1) -> int:
    if part == 1:
        return sum(b > a for a, b in pairwise(sea_floor_depths))
    return sonar_sweep((a + b + c for a, b, c in tripletwise(sea_floor_depths)), part=1)


def sea_floor_depths(report: str) -> Generator[int, None, None]:
    return map(int, report.splitlines())


def main(part: int = 1) -> int:
    with open("2021/data/day01.txt") as f:
        report = f.read()
    return sonar_sweep(sea_floor_depths(report), part)


if __name__ == "__main__":
    report = """199
200
208
210
200
207
240
269
260
263"""
    assert sonar_sweep(sea_floor_depths(report), part=1) == 7
    assert sonar_sweep(sea_floor_depths(report), part=2) == 5
    assert list(tripletwise("ABCDEFG")) == [
        ("A", "B", "C"),
        ("B", "C", "D"),
        ("C", "D", "E"),
        ("D", "E", "F"),
        ("E", "F", "G"),
    ]
    assert list(tripletwise(sea_floor_depths(report))) == [
        (199, 200, 208),
        (200, 208, 210),
        (208, 210, 200),
        (210, 200, 207),
        (200, 207, 240),
        (207, 240, 269),
        (240, 269, 260),
        (269, 260, 263),
    ]

    print(main())
    print(main(part=2))

目前,当我在上面 运行 mypy 时,我得到:

2021/day01.py:22: error: Incompatible return value type (got "map[int]", expected "Generator[int, None, None]")
2021/day01.py:44: error: Argument 1 to "tripletwise" has incompatible type "str"; expected "Iterator[<nothing>]"

我想用类型提示表明 tripletwise() 可以接受任何可迭代对象(例如字符串 "ABCDEFG"sea_floor_depths(report) 的输出)。我也不确定 sea_floor_depths().

的正确 return 类型

至于第一个错误,map 内置函数仅记录为 return 迭代器,因此您可以使用的最具体的类型提示是 Iterator[int]GeneratorIterator 的子类型,仅在使用生成器表达式或生成器函数时出现,而您的函数不会。

对于第二个错误,问题是 str 本身不是 iterators, but rather only iterables,因此适当的类型提示应该是 Iterable[_T_co].