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

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

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


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


当前回答

我做了一些速度测试。让我们假设,如果字符串可能是一个数字,则try/except策略是最快的。如果字符串不可能是数字,并且您对整数检查感兴趣,则值得进行一些测试(isdigit加上标题“-”)。如果您有兴趣检查浮点数,则必须使用try/except代码而不进行转义。

其他回答

这篇文章已经有了很好的答案。我想给出一个稍微不同的观点。

我们可以对字母表进行否定搜索,而不是搜索数字、数字或浮点数。即,我们可以要求程序查看它是否不是字母表。

## Check whether it is not alpha rather than checking if it is digit
print(not "-1.2345".isalpha())
print(not "-1.2345e-10".isalpha())

如果你确定你的字符串是一个格式良好的数字(下面的条件1和条件2),它会很好地工作。但是,如果字符串错误地不是一个格式良好的数字,那么它将失败。在这种情况下,即使字符串不是有效的数字,它也会返回数字匹配。为了解决这种情况,必须有许多基于规则的方法。然而,此时此刻,我想起了正则表达式。以下是三个案例。请注意,正则表达式可以更好,因为我不是正则表达式专家。下面有两个列表:一个用于有效数字,一个用于无效数字。必须拾取有效数字,而不能拾取无效数字。

==条件1:确保字符串为有效数字,但未选择“inf”==

Valid_Numbers = ["1","-1","+1","0.0",".1","1.2345","-1.2345","+1.2345","1.2345e10","1.2345e-10","-1.2345e10","-1.2345E10","-inf"]
Invalid_Numbers = ["1.1.1","++1","--1","-1-1","1.23e10e5","--inf"]

################################ Condition 1: Valid number excludes 'inf' ####################################

Case_1_Positive_Result = list(map(lambda x: not x.isalpha(),Valid_Numbers))
print("The below must all be True")
print(Case_1_Positive_Result)

## This check assumes a valid number. So it fails for the negative cases and wrongly detects string as number
Case_1_Negative_Result = list(map(lambda x: not x.isalpha(),Invalid_Numbers))
print("The below must all be False")
print(Case_1_Negative_Result)
The below must all be True
[True, True, True, True, True, True, True, True, True, True, True, True, True]
The below must all be False
[True, True, True, True, True, True]

==条件2:确保字符串为有效数字,并选择“inf”==

################################ Condition 2: Valid number includes 'inf'  ###################################
Case_2_Positive_Result = list(map(lambda x: x=="inf" or not x.isalpha(),Valid_Numbers+["inf"]))
print("The below must all be True")
print(Case_2_Positive_Result)

## This check assumes a valid number. So it fails for the negative cases and wrongly detects string as number
Case_2_Negative_Result = list(map(lambda x: x=="inf" or not x.isalpha(),Invalid_Numbers+["++inf"]))
print("The below must all be False")
print(Case_2_Negative_Result)
The below must all be True
[True, True, True, True, True, True, True, True, True, True, True, True, True, True]
The below must all be False
[True, True, True, True, True, True, True]

==条件3:字符串不保证是有效数字==

import re
CompiledPattern = re.compile(r"([+-]?(inf){1}$)|([+-]?[0-9]*\.?[0-9]*$)|([+-]?[0-9]*\.?[0-9]*[eE]{1}[+-]?[0-9]*$)")
Case_3_Positive_Result = list(map(lambda x: True if CompiledPattern.match(x) else False,Valid_Numbers+["inf"]))
print("The below must all be True")
print(Case_3_Positive_Result)

## This check assumes a valid number. So it fails for the negative cases and wrongly detects string as number
Case_3_Negative_Result = list(map(lambda x: True if CompiledPattern.match(x) else False,Invalid_Numbers+["++inf"]))
print("The below must all be False")
print(Case_3_Negative_Result)
The below must all be True
[True, True, True, True, True, True, True, True, True, True, True, True, True, True]
The below must all be False
[False, False, False, False, False, False, False]

我也使用了您提到的函数,但很快我注意到字符串“Nan”、“Inf”及其变体被视为数字。因此,我建议您改进函数的版本,该版本将在这些类型的输入上返回false,并且不会失败“1e3”变体:

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False

仅对于非负(无符号)整数,请使用isdigit():

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False

isdigit()文档:Python2,Python3

对于Python 2 Unicode字符串:isnumeric()。

import re
def is_number(num):
    pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
    result = pattern.match(num)
    if result:
        return True
    else:
        return False


​>>>: is_number('1')
True

>>>: is_number('111')
True

>>>: is_number('11.1')
True

>>>: is_number('-11.1')
True

>>>: is_number('inf')
False

>>>: is_number('-inf')
False

这个怎么样:

'3.14'.replace('.','',1).isdigit()

只有当有一个或没有“”时,它才会返回真在数字串中。

'3.14.5'.replace('.','',1).isdigit()

将返回false

编辑:刚刚看到另一条评论。。。可以为其他情况添加.replace(badstuff,“”,maxnum_badstuff)。如果你传递的是盐而不是任意的调味品(参考:xkcd#974),这会很好:P