【问题标题】:Function with generic comprehension return type depending on input argument?具有通用理解返回类型的函数取决于输入参数?
【发布时间】:2020-01-24 13:44:34
【问题描述】:

假设我有一个函数可以转换字符串集合中的字符,例如 -

from typing import Collection

def replace_in_collection(input_collection: Collection[str]) -> Collection[str]:
    return [x.replace('a', 'b') for x in input_collection]

如何以通用方式创建此函数,以便它返回与输入类型相同的集合类型(不仅仅是上面函数示例中的列表)。

所以我想要的是具有以下行为的东西:

my_set = {'ab','ac'}
my_set_result = replace_in_collection(my_set)
type(my_set_result ) # --> set

my_list = ['ab','ac']
my_list_result = replace_in_collection(my_list)
type(my_list_result) # --> list

有没有一种方法可以在不使用单独类型检查的情况下通过理解来创建它?

【问题讨论】:

  • 我认为for x in relevant_channels 是一个错字,应该是for x in input_collection ?
  • 第一篇文章很有趣

标签: python list-comprehension dictionary-comprehension set-comprehension


【解决方案1】:

假设所有类型的集合都接受 iterable 作为 __init__ 参数,那应该可以工作:

def replace_in_collection(input_collection):
    collection_type = type(input_collection)
    return collection_type(x.replace('a', 'b') for x in input_collection)

它适用于 setlisttuple

正如 Chris Rands 所说,您可能应该检查您的输入是否属于受支持的类型:

if not isinstance(input_collection, (set, list, tuple)): # add other types if needed
    raise TypeError(f"input_collection must be of type set, list or tuple, not {type(input_collection).__name__}")

【讨论】:

  • 使用type(obj) 而不是obj.__class__。在类外直接访问 __magic__ 名称被认为是不好的风格,因为这些主要是对运算符或类似运算符的函数的实现支持。
  • 可能值得明确检查类型是否属于集合、列表或元组(或字典)。对于其他类型,这可能会产生错误或意外结果
  • @Chris_Rands 确实如此,但这已经非常明确地提到了。
  • @YevhenKuzmovych 就我而言,只要合同明确记录,我就不会添加任何此类类型检查 - 它是 Python,并且规范是鸭子类型(我们有 Ada用于严格的类型检查 xD)。如果你真的想要添加类型检查,至少使用 Python 方式:使用定义字符串集合的 ABC,将可迭代的产生字符串作为__init__ 参数,注册已知的好类型(list, tuple, set...) 作为你的 ABC 的子类,并检查这个 ABC。
  • @brunodesthuilliers 在哪里?
猜你喜欢
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
  • 2021-05-13
  • 2019-06-07
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多