我有一些Python代码,它运行一个字符串列表,并将它们转换为整数或浮点数(如果可能的话)。对整数执行此操作非常简单

if element.isdigit():
  newelement = int(element)

浮点数比较难。现在我正在使用partition('.')来分割字符串,并检查以确保一侧或两侧都是数字。

partition = element.partition('.')
if (partition[0].isdigit() and partition[1] == '.' and partition[2].isdigit()) 
    or (partition[0] == '' and partition[1] == '.' and partition[2].isdigit()) 
    or (partition[0].isdigit() and partition[1] == '.' and partition[2] == ''):
  newelement = float(element)

这是可行的,但显然if语句有点麻烦。我考虑的另一个解决方案是将转换封装在一个try/catch块中,看看它是否成功,如这个问题所述。

有人有其他想法吗?对分区和尝试/捕获方法的相对优点有什么看法?


当前回答

似乎很多正则表达式都错过了这样或那样的事情。到目前为止,这对我来说是有效的:

(?i)^\s*[+-]?(?:inf(inity)?|nan|(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)\s*$

它允许无穷大(或无穷大)与符号,nan,没有数字之前 十进制,以及前导/尾随空格(如果需要)。^和$是 需要避免将1.2f-2部分匹配为1.2。

如果需要解析某些文件,可以使用[ed]而不是e 其中D用于双精度科学计数法。你会 想要更换它之后或只是更换他们之前检查,因为 float()函数不允许这样做。

其他回答

str(strval).isdigit()

似乎很简单。

处理存储为字符串或整型或浮点数的值

我找到了一个同样有效的方法。需要核实这一点。第一次在这里放东西。

def isfloat(a_str):
    try:
        x=float(a_str)
        if x%1 == 0:
            return False
        elif x%1 != 0: #an else also do
            return True
    except Exception as error:
            return False

Python3方法检查float:

def is_float(element: any) -> bool:
    #If you expect None to be passed:
    if element is None: 
        return False
    try:
        float(element)
        return True
    except ValueError:
        return False

上面的Python2版本:如何将字符串解析为float或int?

总是做单元测试。什么是浮点数,什么不是浮点数,你可能会感到惊讶:

Command to parse                        Is it a float?  Comment
--------------------------------------  --------------- ------------
print(isfloat(""))                      False
print(isfloat("1234567"))               True 
print(isfloat("1_2_3.4"))               True        123.4, underscores ignored
print(isfloat("NaN"))                   True        nan is also float
print(isfloat("123.456"))               True
print(isfloat("123.E4"))                True
print(isfloat(".1"))                    True
print(isfloat("6.523537535629999e-07")) True
print(isfloat("6e777777"))              True        This is same as Inf
print(isfloat("-iNF"))                  True
print(isfloat("1.797693e+308"))         True
print(isfloat("infinity"))              True
print(isfloat("1,234"))                 False
print(isfloat("NULL"))                  False       case insensitive
print(isfloat("NaNananana BATMAN"))     False
print(isfloat(",1"))                    False           
print(isfloat("123.EE4"))               False           
print(isfloat("infinity and BEYOND"))   False
print(isfloat("12.34.56"))              False       Two dots not allowed.
print(isfloat("#56"))                   False
print(isfloat("56%"))                   False
print(isfloat("0E0"))                   True
print(isfloat("x86E0"))                 False
print(isfloat("86-5"))                  False
print(isfloat("True"))                  False       Boolean is not a float.   
print(isfloat(True))                    True        Boolean is a float
print(isfloat("+1e1^5"))                False
print(isfloat("+1e1"))                  True
print(isfloat("+1e1.3"))                False
print(isfloat("+1.3P1"))                False
print(isfloat("-+1"))                   False
print(isfloat("(1)"))                   False       brackets not interpreted

像这样的下沉异常是不好的,因为杀死金丝雀是不好的,因为float方法可能会因为用户输入以外的原因而失败。不要在生命关键软件上使用这样的代码。此外,python已经改变了它的合同,什么unicode字符串可以提升为浮动,所以预计这段代码的行为将在主要版本更新中发生变化。

我们可以使用regex作为: 进口再保险 如果re.match([0 - 9] *。?[0 - 9] +”,< your_string >): print(“它是一个浮点数/int”) 其他: 打印(“这是外星的东西”) 让我用英语解释一下正则表达式,

* -> 0次或更多次 + -> 1次或以上 ? -> 0/1发生

现在,让我们进行转换

'[0-9]* ->允许在0-9之间出现0个或多个数字 \。->后面跟着0或1 '。'(如果你需要检查它是否可以是int/float,否则我们也可以使用?,使用{1}) [0-9]+ ->后跟0个或多个0-9之间的数字

函数is_digit(str)的简化版本,它在大多数情况下都足够了(不考虑指数符号和“NaN”值):

def is_digit(str):
    return str.lstrip('-').replace('.', '').isdigit()