gpt4 book ai didi

Python:验证字符串是否为 float 而不进行转换

转载 作者:行者123 更新时间:2023-12-01 04:01:33 25 4
gpt4 key购买 nike

是否有一种 Pythonic 方法来验证字符串是否表示 float (float() 可以识别的任何输入,例如 -1.6e3) ,而不转换它(并且,理想情况下,不诉诸抛出和捕获异常)?

之前的问题已提交,涉及如何检查字符串是否代表 integerfloat 。答案建议在用户定义的函数中使用 try... except 子句以及 int()float() 内置函数.

但是,这些都没有正确解决速度问题。虽然使用 try... except 习惯用法将转换过程与验证过程联系起来(在某种程度上是正确的),但出于验证目的而检查大量文本的应用程序(任何模式验证器、解析器)将遭受执行实际转换的开销。除了由于数字的实际转换而导致的速度减慢之外,还有由于抛出和捕获异常而导致的速度减慢。 This GitHub gist演示与仅用户定义的验证相比,内置转换代码的成本是两倍(比较 True 情况),并且异常处理时间(False 时间减去 try.. except 版本的 >True 时间就多达 7 次验证。这回答了我关于整数情况的问题。

有效答案将是:以比 try.. except 方法更有效的方式解决问题的函数,对内置功能文档的引用,该内置功能将在未来实现这一点,对现在允许这样做的 Python 包的引用(并且比 try.. except 方法更有效),或者指向为什么这样的解决方案不是 Pythonic 的文档的解释,或者否则会永远不会被实现。具体来说,为了防止困惑,请避免在没有指出官方文档或邮件列表辩论的情况下回答“否”等问题,并避免重复 try.. except 方法。

最佳答案

正如 @John 在评论中提到的,这显示为 answer in another question ,尽管在这种情况下这不是公认的答案。正则表达式和 fastnumbers module 是这个问题的两个解决方案。

但是,值得注意的是(正如 @en_Knight 所做的那样)性能很大程度上取决于输入。如果期望大部分有效输入,则 EAFP方法更快,而且可以说更优雅。如果您不知道要输入什么,那么 LBYL可能更合适。本质上,验证应该期望大部分有效的输入,因此它更适合 try.. except

事实是,对于我识别表格数据文件中的数据类型的用例(以及作为问题的作者,它具有相关性),try.. except 方法更合适:一列要么全是浮点值,要么如果它具有非浮点值,则从该行开始将其视为文本,因此实际测试的浮点值的大多数输入在这两种情况下都是有效的。我想所有其他答案都有意义。

回到答案,对于一般情况,快速数字和正则表达式仍然是有吸引力的解决方案。具体来说,fastnumbers 包似乎适用于除特殊值之外的所有值,例如 Infinity、Inf 和 NaN,如this GitHub gist 。上述答案中的简单正则表达式也是如此(稍作修改 - 删除了尾随的 \b 因为它会导致某些输入失败):

^[-+]?(?:\b[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][-+]?[0-9]+\b)?$

一个更大的版本,确实识别特殊值,在要点中使用,并且具有相同的性能:

^[-+]?(?:[Nn][Aa][Nn]|[Ii][Nn][Ff](?:[Ii][Nn][Ii][Tt][Yy])?|(?:\b[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][-+]?[0-9]+\b)?)$

正则表达式实现在有效输入上慢约 2.8 倍,但在无效输入上快约 2.2 倍。使用 try.. except 时,无效输入的运行速度比有效输入慢约 5 倍,而使用正则表达式时,无效输入的运行速度比有效输入快约 1.3 倍。鉴于这些结果,这意味着当 40% 或更多的预期输入无效时,使用正则表达式是有利的。

fastnumbers 在有效输入上仅快约 1.2 倍,但在无效输入上快约 6.3 倍。

结果如下图所示。我运行了 10^6 次重复,其中有 170 个有效输入和 350 个无效输入(相应加权,因此平均时间是每个单个输入)。由于框太窄,因此未显示颜色,但每列左侧的框描述了有效输入的时间,而右侧的框描述了无效输入。

Timings of methods to validate whether a string holds a valid float value, according to whether inputs are valid or invalid

注意答案经过多次编辑,以反射(reflect)对该问题、此答案和其他答案的评论。为了清楚起见,编辑已被合并。一些评论引用了以前的版本。

关于Python:验证字符串是否为 float 而不进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36406268/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com