如何实现支持单个值与可迭代对象的is_float函数?
问题
想要实现一个is_float函数,既能检测单个值是否可转换为浮点数,也能检测可迭代对象中的所有元素是否均可转换为浮点数。
针对单个值的情况,已实现如下可行的函数:
from typing import Any def is_float(value: Any) -> bool: try: float(value) return True except ValueError: print(f'Cannot convert "{value}" to a floating point number.') return False
针对可迭代对象的情况,尝试了如下实现,但该函数无法兼容非可迭代对象的输入(例如int或string类型的单个值):
from typing import Iterable, Any def is_float(value: Iterable[Any]) -> bool: try: for item in value: float(item) return True except ValueError: print(f'Cannot convert "{item}" to a floating point number.') return False
请问除了添加判断可迭代对象是否仅含单个值的if语句之外,有没有更简便的实现方法?
解决方案
方法一:统一逻辑区分处理
核心是把字符串单独排除(因为字符串本身是可迭代对象,但我们需要将其视为单个值),然后分两种情况处理:非迭代/字符串类型直接检查,其他可迭代对象遍历检查。
from typing import Any, Iterable def is_float(value: Any) -> bool: # 判断是否为需要遍历的可迭代对象(排除字符串、字节串) def need_iterate(v) -> bool: return isinstance(v, Iterable) and not isinstance(v, (str, bytes)) try: if need_iterate(value): for item in value: float(item) else: float(value) return True except ValueError: # 根据类型输出对应错误提示 err_target = item if need_iterate(value) else value print(f'Cannot convert "{err_target}" to a floating point number.') return False
方法二:用all()简化迭代检查
利用生成器表达式结合all()函数,把迭代对象的检查逻辑压缩,让代码更简洁:
from typing import Any, Iterable def is_float(value: Any) -> bool: try: if isinstance(value, Iterable) and not isinstance(value, (str, bytes)): return all(float(item) for item in value) else: float(value) return True except ValueError: # 获取出错的目标值,优先取迭代中的item,否则取输入值 err_target = locals().get("item", value) print(f'Cannot convert "{err_target}" to a floating point number.') return False
方法三:类型重载(Python 3.10+)
如果使用Python 3.10及以上版本,可以用@overload定义不同的函数签名,让类型提示更清晰,同时保持逻辑统一:
from typing import Any, Iterable, overload @overload def is_float(value: str | int | float | bytes) -> bool: ... @overload def is_float(value: Iterable[Any]) -> bool: ... def is_float(value: Any) -> bool: try: if isinstance(value, Iterable) and not isinstance(value, (str, bytes)): for item in value: float(item) else: float(value) return True except ValueError: err_target = locals().get("item", value) print(f'Cannot convert "{err_target}" to a floating point number.') return False
以上方法都无需单独判断可迭代对象的元素数量,通过明确区分处理逻辑实现了单值与可迭代对象的兼容。
内容的提问来源于stack exchange,提问作者Riddeen
相关产品推荐
相关产品推荐

