如何检查字符串是否代表数字(浮点数或整数)?

2024-11-20 08:44:00
admin
原创
8
摘要:问题描述:如何在 Python 中检查字符串是否代表数值?def is_number(s): try: float(s) return True except ValueError: return False 上述方法可行,但似乎比较笨重。如果您...

问题描述:

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

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

上述方法可行,但似乎比较笨重。


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


解决方案 1:

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

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

文档isdigit():Python2、Python3

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

解决方案 2:

它不仅丑陋而且缓慢

我对这两点都有异议。

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

我不确定还有什么比上面的方法更快。它调用函数并返回。Try/Catch 不会带来太多开销,因为最常见的异常无需大量搜索堆栈框架即可捕获。

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

  • 一个数字(如果数字有效)

  • 状态代码(例如通过 errno)或异常表明无法解析有效数字。

以 C 为例,它以多种方式解决了这个问题。Python 对此进行了清晰明确的阐述。

我认为您执行此操作的代码非常完美。

解决方案 3:

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

我做了一些基准测试,比较了不同的方法

def is_number_tryexcept(s):
    """ Returns True if string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False
       
import re    
def is_number_regex(s):
    """ Returns True if 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 if string is a number. """
    return s.replace('.','',1).isdigit()

如果字符串不是数字,except 块会非常慢。但更重要的是,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('     -', f.__name__)

浮点表示法“.1234”不受以下系统支持:

  • 是数字_正则表达式

科学1 = '1.000000e+50' 科学2 = '1e50'

print('科学计数法“1.000000e+50”不支持:') for f in funcs: if not f(scientific1): print('\t -', f. name )

print('不支持科学计数法“1e50”:') for f in funcs: if not f(scientific2): print('\t -', f. name )

科学计数法“1.000000e+50”不受以下系统支持:

  • 是数字_正则表达式

  • is_number_repl_isdigit

科学记数法“1e50”不受以下系统支持:

  • 是数字_正则表达式

  • 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 if string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True if 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 if string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True if string is a number. """
    return s.replace('.','',1).isdigit()

在此处输入图片描述

解决方案 4:

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

如果您希望 is_number 对“NaN”返回 FALSE,则此代码将不起作用,因为 Python 会将其转换为非数字的数字表示形式(讨论身份问题):

>>> float('NaN')
nan

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

G.

解决方案 5:

这个怎么样:

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

仅当数字字符串中有一个或没有“。”时才会返回 true。

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

将返回 false

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

解决方案 6:

在 Alfe 指出您不需要单独检查浮点数因为复杂处理两者之后进行了更新:

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True

之前说过:在某些罕见的情况下,您可能还需要检查复数(例如 1 + 2i),它不能用浮点数表示:

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True

解决方案 7:

它不仅外观丑陋、速度慢,而且显得笨重。

可能需要一些时间来适应,但这是 Python 式的做法。正如已经指出的那样,其他选择更糟糕。但这样做还有一个好处:多态性。

鸭子类型背后的核心思想是“如果它走路和说话像鸭子,那么它就是鸭子。”如果你决定需要子类化字符串,以便可以改变确定某事物是否可以转换为浮点数的方式,该怎么办?或者,如果你决定完全测试其他对象,该怎么办?你可以做这些事情,而不必更改上述代码。

其他语言通过使用接口来解决这些问题。我将留到下次再分析哪种解决方案更好。不过,重点是 Python 明显偏向于鸭子类型,如果您打算用 Python 进行大量编程,您可能必须习惯这样的语法(但这并不意味着您必须喜欢它)。

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

解决方案 8:

该答案提供了具有示例的分步指南,用于查找字符串:

  • 正整数

  • 正/负 - 整数/浮点数

  • 如何在检查数字时丢弃“NaN”(非数字)字符串?

检查字符串是否为整数

您可以用它str.isdigit()来检查给定的字符串是否是整数。

样本结果:

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False

检查字符串是否为正数/负数 - 整数/浮点数

str.isdigit()返回False字符串是否为负数浮点数。例如:

# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False

如果您还想检查整数和float,那么您可以编写自定义函数来检查它:

def is_number(n):
    try:
        float(n)   # Type-casting the string to `float`.
                   # If string is not a valid `float`, 
                   # it'll raise `ValueError` exception
    except ValueError:
        return False
    return True

示例运行:

>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True
 
>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False

检查数字时丢弃“NaN”(非数字)字符串

上述函数将返回True“NAN”(非数字)字符串,因为对于 Python 来说,它是有效的浮点数,表示它不是数字。例如:

>>> is_number('NaN')
True

为了检查数字是否为“NaN”,你可以使用math.isnan()

>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True

或者,如果您不想导入其他库来检查这一点,那么您可以简单地通过使用将其与自身进行比较来检查它==Falsenan浮点数与自身进行比较时,Python 会返回。例如:

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False

因此,上述函数is_number可以更新为False返回"NaN"

def is_number(n):
    is_number = True
    try:
        num = float(n)
        # check for "nan" floats
        is_number = num == num   # or use `math.isnan(num)`
    except ValueError:
        is_number = False
    return is_number

示例运行:

>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False

is_numberPS:根据数字类型,每次检查的每个操作都会产生额外的开销。选择适合您要求的功能版本。

解决方案 9:

为了int使用这个:

>>> "1221323".isdigit()
True

float我们需要一些技巧 ;-)。每个浮点数都有一个点...

>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False

对于负数也只需添加lstrip()

>>> '-12'.lstrip('-')
'12'

现在我们得到了一个通用的方法:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False

解决方案 10:

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

如果您发现自己陷入了性能困境,则可以使用名为fastnumbers的新第三方模块,该模块提供了一个名为isfloat 的函数。坦白说,我是该模块的作者。我已将其结果包含在下面的计时中。


from __future__ import print_function
import timeit

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

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

'''

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

'''

fn_method = '''\nfrom 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两案均胜出

解决方案 11:

只需模仿 C

在 C# 中,有两个不同的函数可以处理标量值的解析:

  • Float.解析()

  • Float.TryParse()

浮点数.解析():

def parse(string):
    try:
        return float(string)
    except Exception:
        throw TypeError

注意:如果您想知道为什么我将异常更改为 TypeError,请参阅文档。

float.try_parse():

def try_parse(string, fail=None):
    try:
        return float(string)
    except Exception:
        return fail;

注意:您不想返回布尔值“False”,因为它仍然是一种值类型。None 更好,因为它表示失败。当然,如果您想要不同的东西,您可以将 fail 参数更改为您想要的任何内容。

要扩展 float 以包含“parse()”和“try_parse()”,您需要对“float”类进行 monkeypatch 以添加这些方法。

如果您想要尊重预先存在的功能,代码应该是这样的:

def monkey_patch():
    if(!hasattr(float, 'parse')):
        float.parse = parse
    if(!hasattr(float, 'try_parse')):
        float.try_parse = try_parse

旁注:我个人更喜欢称之为“Monkey Punching”,因为当我这样做时感觉像是在滥用语言,但 YMMV。

用法:

float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2

大圣人派森纳斯对教廷夏普西斯说道:“你能做的任何事,我都能做得更好;我能做任何事比你更好。”

解决方案 12:

我知道这已经很老了,但我想补充一个答案,我相信它涵盖了得票最高的答案中缺少的信息,这对于任何发现这一点的人来说都非常有价值:

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

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

x.replace('-','').isdigit()
适用于检查 x 是否为负数。(检查 - 在第一个位置)

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

x.replace(':','').isdigit()
适用于检查 x 是否为比率。

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

解决方案 13:

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

解决方案 14:

您可以使用 Unicode 字符串,它们有一种方法可以执行您想要的操作:

>>> s = u"345"
>>> s.isnumeric()
True

或者:

>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True

http://www.tutorialspoint.com/python/string_isnumeric.htm

http://docs.python.org/2/howto/unicode.html

解决方案 15:

我想看看哪种方法最快。总体而言,该check_replace函数给出了最佳和最一致的结果。该函数给出了最快的结果check_exception,但前提是没有引发异常 - 这意味着它的代码是最高效的,但引发异常的开销相当大。

请注意,检查转换是否成功是唯一准确的方法,例如,这种方法有效,check_exception但其他两个测试函数将对有效浮点数返回 False:

huge_number = float('1e+100')

基准代码如下:

import time, re, random, string

ITERATIONS = 10000000

class Timer:    
    def __enter__(self):
        self.start = time.clock()
        return self
    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def check_regexp(x):
    return re.compile("^d*.?d*$").match(x) is not None

def check_replace(x):
    return x.replace('.','',1).isdigit()

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

to_check = [check_regexp, check_replace, check_exception]

print('preparing data...')
good_numbers = [
    str(random.random() / random.random()) 
    for x in range(ITERATIONS)]

bad_numbers = ['.' + x for x in good_numbers]

strings = [
    ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
    for x in range(ITERATIONS)]

print('running test...')
for func in to_check:
    with Timer() as t:
        for x in good_numbers:
            res = func(x)
    print('%s with good floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in bad_numbers:
            res = func(x)
    print('%s with bad floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in strings:
            res = func(x)
    print('%s with strings: %s' % (func.__name__, t.interval))

以下是在 2017 款 MacBook Pro 13 上使用 Python 2.7.10 的结果:

check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169

以下是在 2017 款 MacBook Pro 13 上使用 Python 3.6.5 的结果:

check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002

以下是在 2017 款 MacBook Pro 13 上运行 PyPy 2.7.13 的结果:

check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056

解决方案 16:

输入可能如下:

a="50"
b=50
c=50.1
d="50.1"


1-常规输入:

此函数的输入可以是一切!

判断给定变量是否为数字。数字字符串由可选符号、任意数量的数字、可选小数部分和可选指数部分组成。因此 +0123.45e6 是有效的数字值。不允许使用十六进制(例如 0xf4c3b00c)和二进制(例如 0b10100111001)表示法。

is_numeric函数

import ast
import numbers              
def is_numeric(obj):
    if isinstance(obj, numbers.Number):
        return True
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            #if used + or - in digit :
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

测试:

>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True

is_float函数

查找给定的变量是否为浮点数。浮点字符串由可选符号、任意数量的数字等组成……

import ast

def is_float(obj):
    if isinstance(obj, float):
        return True
    if isinstance(obj, int):
        return False
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        if not isinstance(nodes[-1].n, float):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

测试:

>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True

ast是什么?


2-如果您确信变量内容是字符串

使用str.isdigit()方法

>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True

3-数字输入:

检测 int 值:

>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>> 

检测浮动:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True

解决方案 17:

对于浮点数,最常见的情况是,人们希望处理整数和小数。我们以字符串"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)

解决方案 18:

所以把它们放在一起,检查 Nan、无穷大和复数(似乎它们是用 j 而不是 i 指定的,即 1+2j)结果是:

def is_number(s):
    try:
        n=str(float(s))
        if n == "nan" or n=="inf" or n=="-inf" : return False
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False
    return True

解决方案 19:

我认为您的解决方案很好,但是有一个正确的正则表达式实现。

似乎有很多人讨厌这些答案中的正则表达式,我认为这是不合理的,正则表达式可以相当干净、正确和快速。这真的取决于你想做什么。最初的问题是如何“检查字符串是否可以表示为数字(浮点数)”(按照你的标题)。假设你在检查它是否有效后会想要使用数字/浮点值,在这种情况下你的 try/except 很有意义。但是,如果出于某种原因,你只是想验证字符串是否数字,那么正则表达式也可以正常工作,但很难得到正确的结果。例如,我认为到目前为止,大多数正则表达式答案都不能正确解析没有整数部分的字符串(例如“.7”),就 python 而言,这是一个浮点数。在单个正则表达式中检查这一点有点棘手,因为小数部分不是必需的。我包含了两个正则表达式来展示这一点。

这确实提出了一个有趣的问题,即“数字”是什么。您是否包括“inf”,它在 Python 中作为浮点数有效?或者您是否包括“数字”,但可能无法在 Python 中表示(例如大于浮点最大值的数字)。

在解析数字时也存在歧义。例如,“--20”怎么办?这是一个“数字”吗?这是表示“20”的合法方式吗?Python 允许您执行“var = --20”并将其设置为 20(尽管这实际上是因为它将其视为表达式),但 float(“--20”) 不起作用。

无论如何,如果没有更多的信息,这里有一个正则表达式,我相信它涵盖了python 解析的所有整数和浮点数。

# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           mantissa (34)
                            #                    exponent (E+56)

# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           OR
                            #             int/mantissa (12.34)
                            #                            exponent (E+56)

def is_float(str):
  return True if FLOAT_REGEXP.match(str) else False

一些示例测试值:

True  <- +42
True  <- +42.42
False <- +42.42.22
True  <- +42.42e22
True  <- +42.42E-22
False <- +42.42e-22.8
True  <- .42
False <- 42nope

运行@ron-reiter答案中的基准测试代码表明,这个正则表达式实际上比普通正则表达式更快,并且处理坏值的速度比异常快得多,这是有道理的。结果:

check_regexp with good floats: 18.001921
check_regexp with bad floats: 17.861423
check_regexp with strings: 17.558862
check_correct_regexp with good floats: 11.04428
check_correct_regexp with bad floats: 8.71211
check_correct_regexp with strings: 8.144161
check_replace with good floats: 6.020597
check_replace with bad floats: 5.343049
check_replace with strings: 5.091642
check_exception with good floats: 5.201605
check_exception with bad floats: 23.921864
check_exception with strings: 23.755481

解决方案 20:

str.isnumeric()

True如果字符串中的所有字符都是数字字符,并且至少有一个字符,则返回False,否则返回。数字字符包括数字字符,以及所有具有 Unicode 数字值属性的字符,例如 U+2155、VULGAR FRACTION ONE FIFTH。正式来说,数字字符是那些具有属性值 Numeric_Type=Digit、Numeric_Type=Decimal 或 Numeric_Type=Numeric 的字符。

str.isdecimal()

True如果字符串中的所有字符都是十进制字符且至少有一个字符,则返回False,否则返回。十进制字符是那些可用于形成十进制数字的字符,例如 U+0660,阿拉伯印度数字零。正式来说,十进制字符是 Unicode 通用类别“Nd”中的字符。

两者均适用于 Python 3.0 中的字符串类型。

解决方案 21:

我需要确定字符串是否转换为基本类型(float、int、str、bool)。在互联网上找不到任何东西后,我创建了这个:

def str_to_type (s):
    """ Get possible cast type for a string

    Parameters
    ----------
    s : string

    Returns
    -------
    float,int,str,bool : type
        Depending on what it can be cast to

    """    
    try:                
        f = float(s)        
        if "." not in s:
            return int
        return float
    except ValueError:
        value = s.upper()
        if value == "TRUE" or value == "FALSE":
            return bool
        return type(s)

例子

str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode       

您可以捕获类型并使用它

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 

解决方案 22:

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

解决方案 23:

RyanN 建议

如果要对 NaN 和 Inf 返回 False,请将行更改为 x = float(s); return (x == x) and (x - 1 != x)。这应该对除 Inf 和 NaN 之外的所有浮点数返回 True

但这并不完全有效,因为对于足够大的浮点数,x-1 == x返回 true。例如,2.0**54 - 1 == 2.0**54

解决方案 24:

我正在研究一个问题,这个问题引导我进入这个主题,即如何以最直观的方式将数据集合转换为字符串和数字。阅读原始代码后,我意识到我需要的在两个方面有所不同:

1 - 如果字符串表示整数,我想要一个整数结果

2 - 我想要一个数字或字符串结果粘贴到数据结构中

所以我调整了原始代码来生成这个导数:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s

解决方案 25:

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

解决方案 26:

此代码处理指数、浮点数和整数,无需使用正则表达式。

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False

解决方案 27:

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

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

    except ValueError:
        return float(value)

解释:

如果字符串中的值是 a ,float而我首先尝试将其解析为int,它将抛出ValueError。因此,我捕获该错误并将该值解析为float并返回。

解决方案 28:

以下是我的简单做法。假设我循环遍历一些字符串,如果它们是数字,我想将它们添加到数组中。

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

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

解决方案 29:

您可以通过返回比 True 和 False 更有用的值来以有用的方式概括异常技术。例如,此函数将引号放在字符串周围,但保留数字。这正是我为 R 进行快速而粗略的筛选以进行一些变量定义所需要的。

import sys

def fix_quotes(s):
    try:
        float(s)
        return s
    except ValueError:
        return '"{0}"'.format(s)

for line in sys.stdin:
    input = line.split()
    print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'

解决方案 30:

我也使用了你提到的函数,但很快我注意到字符串“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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用