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

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

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


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


当前回答

一个快速而简单的选项是检查数据类型:

def is_number(value):
    return type(value) in [int, float]

或者,如果要测试字符串的值是否为数字:

def isNumber (value):
    return True if type(value) in [int, float] else str(value).replace('.','',1).isdigit()

测验:

>>> isNumber(1)
True

>>> isNumber(1/3)
True

>>> isNumber(1.3)
True

>>> isNumber('1.3')
True

>>> isNumber('s1.3')
False

其他回答

我知道这是一个特别古老的问题,但我想补充一个答案,我相信这个答案涵盖了投票最高的答案中缺少的信息,对任何发现这一点的人来说都非常有价值:

对于以下每个方法,如果需要接受任何输入,请将它们与计数连接。(假设我们使用的是整数的语音定义,而不是0-255等)

x.isdigit()用于检查x是否为整数。

x.replace('-','').idigit()用于检查x是否为负值。(值机柜台第一位)

x.replace('.','').idigit()用于检查x是否为小数。

x.replace(“:”,“”).idigit()用于检查x是否为比率。

x.replace('/','',1).idigit()用于检查x是否为分数。

强制转换为float并捕获ValueError可能是最快的方法,因为float()专门用于此。任何其他需要字符串解析(正则表达式等)的操作都可能会比较慢,因为它没有针对该操作进行调整。我的0.02美元。

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

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

## 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]

用户助手功能:

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)])

对于非数字字符串,请尝试:except:实际上比正则表达式慢。对于有效数字的字符串,正则表达式速度较慢。因此,适当的方法取决于您的输入。

如果您发现自己处于性能绑定中,可以使用名为fastnumbers的新第三方模块,该模块提供一个名为isfloat的函数。完全披露,我是作者。我已将其结果包含在以下时间中。


from __future__ import print_function
import timeit

prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''

prep_try_method = '''\
def is_number_try(val):
    try:
        float(val)
        return True
    except ValueError:
        return False

'''

prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
    return bool(float_match(val))

'''

fn_method = '''\
from fastnumbers import isfloat

'''

print('Try with non-number strings', timeit.timeit('is_number_try(x)',
    prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
    prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
    prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
    prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
    prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
    prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()

Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds

Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds

fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds

如你所见

try:except:对于数字输入很快,但对于无效输入很慢当输入无效时,正则表达式非常有效fastnumbers在这两种情况下都获胜