如何检查字符串是否表示数字(float或int)

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

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

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

上面的作品,但它似乎笨拙。

如果您正在测试的内容来自用户输入,则即使它表示intfloat,它仍然是一个字符串。请参阅How can I read inputs as numbers?以转换输入,以及Asking the user for input until they give a valid response以确保输入表示int1)。

1729

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

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False
Documentation forisdigit():Python2,Python3

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

767

这不仅丑陋而且缓慢

我会两者都争论。

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

我不确定任何东西都可能比上面更快。它调用函数并返回。Try / Catch 不会引入太多开销,因为最常见的异常是在没有广泛搜索堆栈帧的情况下捕获的。

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

一个数字,如果该数字有效

状态代码(例如,通过 errno)或异常,以显示无法解析有效数字。

C(作为一个例子)有很多方法可以解决这个问题。

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

283

TL;DR最好的解决方案是s.replace('.','',1).isdigit()

我做了一些benchmarks比较不同的方法

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False
import re    
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re.match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True
def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

如果字符串不是数字,那么 except-block 就相当慢了。但更重要的是,try-except 方法是正确处理科学符号的唯一方法。

funcs = [
          is_number_tryexcept, 
          is_number_regex,
          is_number_repl_isdigit
          ]
a_float = '.1234'
print('Float notation ".1234" is not supported by:')
for f in funcs:
    if not f(a_float):
        print('\t -', f.__name__)

以下项不支持浮点表示法“.1234”:
-is_number_regex

scientific1 = '1.000000e+50'
scientific2 = '1e50'
print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
    if not f(scientific1):
        print('\t -', f.__name__)
print('Scientific notation "1e50" is not supported by:')
for f in funcs:
    if not f(scientific2):
        print('\t -', f.__name__)


-is_number_regex
-is_number_repl_isdigit
不支持科学记法“1.000000 e + 50”:
-is_number_regex
-is_number_repl_isdigit

编辑:基准测试结果

import timeit
test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}
for t in test_cases:
    for f in funcs:
        f = f.__name__
        times_n[f].append(min(timeit.Timer('%s(t)' %f, 
                      'from __main__ import %s, t' %f)
                              .repeat(repeat=3, number=1000000)))

其中测试了以下功能

from re import match as re_match
from re import compile as re_compile
def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re_match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True
comp = re_compile("^\d+?\.\d+?$")    
def compiled_regex(s):
    """ Returns True is string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True
def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

enter image description here

78

您可能需要考虑一个例外:字符串 'NaN'

如果你想 is_number 为 'NaN' 返回 FALSE,这段代码将无法工作,因为 Python 将其转换为非数字的数字表示(谈论身份问题):

>>> float('NaN')
nan

否则,我实际上应该感谢你现在广泛使用的代码。:)

G.

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(251)
自动生成的 AppData/Local文件夹“创建不正确”
上一篇
clojure懒惰序列和 letfn
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(7条)