在Python中检查字符串是否可以转换为浮点数

295

我有一些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代码块来尝试转换并查看是否成功,就像这个问题中描述的那样。

大家有其他的想法吗?对分隔符和try/catch方法的优劣有什么看法?


准确地说,在Python中并不存在类型转换这样的概念。因此,标签“type-conversion”是误导性的,而在某些语言中,它是一个明确定义的术语。 - user5538922
@bombs 没有类型转换?那这是什么:print(type("1"));print(type(int("1"))),输出:<class 'str'> <class 'int'>?这不是从 strint 的类型转换吗? - ggorlen
@ggorlen 一点也不。你只是从其他对象创建新对象。沿途在堆中分配新的内存空间。没有任何转换。 - user5538922
1
我明白你的意思,但那似乎有点学究了。如果有人说“将字符串转换为浮点数”,意图似乎是非常普遍清晰的。 - ggorlen
你为什么使用.isdigit()而不是.isnumeric()来判断正整数? - Charlie Parker
24个回答

2
一个简单的函数,可以获取数字类型,而不需要使用try和except操作。
def number_type(number):
    if number.isdigit():
        return int(number)
    elif number.replace(".","").isdigit():
        return float(number)
    else:
        return(type(number))

number_type("192.168.0.1") 给出 ValueError: 无法将字符串转换为浮点数: '192.168.0.1' - Thierry Lathuille

2

看起来很多给定的正则表达式都会漏掉某些东西。到目前为止,这个对我一直有效:

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

它允许带符号的无穷大(或inf)、nan、小数点前没有数字以及前导/尾随空格(如果需要)。需要使用^$来避免将1.2f-2部分匹配为1.2
如果需要解析一些使用双精度科学计数法的文件,可以使用[ed]替代e。在检查之前或之后替换它们,因为float()函数不允许使用D

2

您可以使用try-except-else语句来捕获当传入的值无法转换为浮点数时引发的任何转换/值错误。


  def try_parse_float(item):
      result = None
      try:
        float(item)
      except:
        pass
      else:
        result = float(item)
      return result

2
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - double-beep

1
我尝试了上述一些简单的选项,使用一个try测试来转换为浮点数,并发现大多数答案存在问题。
简单测试(类似于上面的答案):
entry = ttk.Entry(self, validate='key')
entry['validatecommand'] = (entry.register(_test_num), '%P')

def _test_num(P):
    try: 
        float(P)
        return True
    except ValueError:
        return False

问题出现在以下情况下:
  • 您输入'-'以开始负数:

然后尝试执行float('-'),但失败了

  • 您输入一个数字,但随后尝试删除所有数字

然后尝试执行float(''),同样也会失败

我提供的快速解决方案是:

def _test_num(P):
    if P == '' or P == '-': return True
    try: 
        float(P)
        return True
    except ValueError:
        return False

1
我在寻找一些类似的代码,但看起来使用try/except是最好的方法。 这是我正在使用的代码。如果输入无效,它包括一个重试函数。我需要检查输入是否大于0,如果是,则将其转换为浮点数。
def cleanInput(question,retry=False): 
    inputValue = input("\n\nOnly positive numbers can be entered, please re-enter the value.\n\n{}".format(question)) if retry else input(question)
    try:
        if float(inputValue) <= 0 : raise ValueError()
        else : return(float(inputValue))
    except ValueError : return(cleanInput(question,retry=True))


willbefloat = cleanInput("Give me the number: ")

1
尝试转换为浮点数。如果出现错误,请打印ValueError异常。
try:
    x = float('1.23')
    print('val=',x)
    y = float('abc')
    print('val=',y)
except ValueError as err:
    print('floatErr;',err)

输出:

val= 1.23
floatErr: could not convert string to float: 'abc'

1
将字典作为参数传递,它将转换可以转换为浮点数的字符串,并保留其他字符串。
def covertDict_float(data):
        for i in data:
            if data[i].split(".")[0].isdigit():
                try:
                    data[i] = float(data[i])
                except:
                    continue
        return data

0
你可以创建一个isfloat()函数,用它代替isdigit()来判断整数和浮点数,但是不能用于字符串,因为结果不符合预期。
a = raw_input('How much is 1 share in that company? \n')

def isfloat(num):
    try:
        float(num)
        return True
    except:
        return False
       
while not isfloat(a):
    print("You need to write a number!\n")
    a = raw_input('How much is 1 share in that company? \n')

0

这个非常好用:

[dict([a,int(x) if isinstance(x, str)
 and x.isnumeric() else float(x) if isinstance(x, str)
 and x.replace('.', '', 1).isdigit() else x] for a, x in json_data.items())][0]

0

我已经编写了自己的函数。与其使用float(value),我使用floatN()或floatZ()。如果该值无法转换为浮点数,则返回None或0.0。我将它们保存在一个名为safeCasts的模块中。

def floatN(value):
    try:
        if value is not None:
            fvalue = float(value)
        else:
            fvalue = None
    except ValueError:
        fvalue = None

    return fvalue


def floatZ(value):
    try:
        if value is not None:
            fvalue = float(value)
        else:
            fvalue = 0.0
    except ValueError:
        fvalue = 0.0

    return fvalue

在其他模块中,我会导入它们。

from safeCasts import floatN, floatZ

那么,使用floatN(value)或floatZ(value)代替float()即可。显然,您可以将此技术用于任何需要的转换函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接