如何在Python中检查字符串是否表示数值?

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

上述方法可行,但似乎很笨拙。


如果您正在测试的内容来自用户输入,那么即使它表示int或float,它仍然是一个字符串。请参阅如何将输入读取为数字?用于转换输入,并询问用户输入,直到他们给出有效响应以确保输入在继续之前表示int或float(或其他要求)。


当前回答

用户助手功能:

def if_ok(fn, string):
  try:
    return fn(string)
  except Exception as e:
    return None

然后

if_ok(int, my_str) or if_ok(float, my_str) or if_ok(complex, my_str)
is_number = lambda s: any([if_ok(fn, s) for fn in (int, float, complex)])

其他回答

我知道我参加晚会迟到了,但我想出了一个不在这里的解决方案:此解决方案遵循Python中的EAFP原则

def get_number_from_string(value):
    try:
        int_value = int(value)
        return int_value

    except ValueError:
        return float(value)

说明:

如果字符串中的值是一个浮点数,并且我首先尝试将其解析为一个int,那么它将抛出一个ValueError。因此,我捕捉到该错误,并将该值解析为float和return。

在浮点数的最常见情况下,我们希望处理整数和小数。让我们以字符串“1.1”为例。

我会尝试以下方法之一:

1.>isnumeric()

word = "1.1"

"".join(word.split(".")).isnumeric()
>>> True

2.>isdigit()

word = "1.1"

"".join(word.split(".")).isdigit()
>>> True

3.>isdecimal()

word = "1.1"

"".join(word.split(".")).isdecimal()
>>> True

速度:

► 所有上述方法具有相似的速度。

%timeit "".join(word.split(".")).isnumeric()
>>> 257 ns ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit "".join(word.split(".")).isdigit()
>>> 252 ns ± 11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit "".join(word.split(".")).isdecimal()
>>> 244 ns ± 7.17 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

这是我的简单方法。假设我在循环一些字符串,如果它们变成数字,我想将它们添加到数组中。

try:
    myvar.append( float(string_to_check) )
except:
    continue

如果myvar.apppend是一个数字,则将其替换为要对字符串执行的任何操作。其想法是尝试使用float()操作,并使用返回的错误来确定字符串是否为数字。

这不仅丑陋而且缓慢

我对这两个都有异议。

正则表达式或其他字符串解析方法会更丑陋、更慢。

我不确定有什么比上面提到的更快。它调用函数并返回。Try/Catch不会带来太多的开销,因为最常见的异常是在不大量搜索堆栈帧的情况下捕获的。

问题是任何数值转换函数都有两种结果

一个数字,如果该数字有效状态代码(例如,通过errno)或异常,表明无法解析任何有效数字。

C(作为一个例子)通过多种方式解决了这个问题。Python将其清晰明确地展示出来。

我认为你这样做的代码是完美的。

这不仅是丑陋和缓慢的,而且显得笨拙。

这可能需要一些时间来适应,但这是一种蟒蛇式的方式。正如已经指出的那样,替代方案更糟糕。但这样做还有一个好处:多态性。

duck类型背后的核心思想是“如果它像鸭子一样走路和说话,那么它就是鸭子。”如果您决定需要对字符串进行子类化,这样您就可以更改确定某个对象是否可以转换为float的方式,该怎么办?或者如果你决定完全测试其他对象呢?您可以在不必更改上述代码的情况下执行这些操作。

其他语言通过使用接口来解决这些问题。我将保存对哪个解决方案更适合另一个线程的分析。不过,重点是python显然是在公式中的鸭子类型方面,如果你打算用python进行大量编程,你可能必须习惯这样的语法(但这并不意味着你当然要喜欢它)。

还有一点您可能需要考虑:与许多其他语言相比,Python在抛出和捕获异常方面非常快(例如,比.Net快30倍)。见鬼,语言本身甚至抛出异常来传达非异常的正常程序条件(每次使用for循环时)。因此,在您注意到一个重大问题之前,我不会太担心这段代码的性能方面。