类型提示返回与输入相同类型的 Sized 迭代?

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

以下代码有效,但根据我如何修复类型提示,PyCharm 或 mypy 会抱怨它。 我已经尝试过 Sized、Iterable 和 Collection 作为 S 类型。

T = TypeVar("T")
S = TypeVar("S", bound=Collection[T])


def limit(i: S, n: int) -> S:
    """
    Limits the size of the input iterable to n.  Truncation is randomly chosen.
    """
    if len(i) <= n:
        return i
    return type(i)(random.sample(list(i), n))

我想要的是类似

random.sample
的东西,具有以下两个属性:

  1. 如果
    n > len(i)
    ,则返回
    i
    而不是抛出错误
  2. 输出的 Collection 类型应与输入相同。
    list[int | str]
    输入 =
    list[int | str]
    输出;
    set[float]
    输入 =
    set[float]
    输出。

如果标准库中已经有类似的东西,我将使用它。

python pycharm python-typing mypy
1个回答
0
投票

以下代码满足您对列表和集合的规定要求:

import random
from typing import TypeVar, Union, Sized, Iterable


def limit(i: Union[TypeVar, Sized, Iterable], n: int) -> Union[TypeVar, Sized, Iterable]:
    if type(i) is not set and type(i) is not list:
        return i
    if len(i) <= n:
        return i
    return type(i)(random.sample(list(i), n))


my_list_of_ints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
out = limit(my_list_of_ints, 3)
print(out)

my_set_of_ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
out = limit(my_set_of_ints, 3)
print(out)

my_list_of_floats = [1.2, 2.2, 3.3, 4.1, 5.6, 6.7, 7.8, 8.5, 9.3, 10.2]
out = limit(my_list_of_floats, 3)
print(out)

my_list_of_strs = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
out = limit(my_list_of_strs, 3)
print(out)

my_set_of_floats = {1.2, 2.2, 3.3, 4.1, 5.6, 6.7, 7.8, 8.5, 9.3, 10.2}
out = limit(my_set_of_floats, 3)
print(out)

my_tuple = (1, 2, 3, 4, 5, 6, 7, 8)
out = limit(my_tuple, 3)
print(out)
© www.soinside.com 2019 - 2024. All rights reserved.