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

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

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


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


当前回答

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

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

其他回答

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

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

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

我也有类似的问题。我想将字符串列表转换为浮点数,而不是定义isNumber函数,这在高级术语中是:

[ float(s) for s in list if isFloat(s)]

在给定的情况下,我们不能真正将float与isFloat函数分开:这两个结果应该由同一个函数返回。此外,如果float失败,整个过程将失败,而不仅仅是忽略错误元素。此外,“0”是一个有效的数字,应包含在列表中。当过滤掉坏元素时,一定不要排除0。

因此,必须以某种方式修改上述理解:

如果列表中的任何元素都无法转换,请忽略它并不要引发异常避免为每个元素多次调用float(一个用于转换,另一个用于测试)如果转换后的值为0,则它仍应出现在最终列表中

我提出了一个以C#的可空数值类型为灵感的解决方案。这些类型在内部由一个结构表示,该结构具有数值,并添加一个布尔值,指示该值是否有效:

def tryParseFloat(s):
    try:
        return(float(s), True)
    except:
        return(None, False)

tupleList = [tryParseFloat(x) for x in list]
floats = [v for v,b in tupleList if b]

输入可能如下:

a=“50”b=50c=50.1d=“50.1”


1-一般输入:

这个函数的输入可以是一切!

查找给定变量是否为数字。数字字符串由可选符号、任意位数、可选小数部分和可选指数部分组成。因此,+0123.45e6是一个有效的数值。不允许使用十六进制(例如0xf4c3b000c)和二进制(例如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函数

查找给定变量是否为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

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

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

isdigit()文档:Python2,Python3

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

我需要确定字符串是否转换为基本类型(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)