提问



在Python中,如何将"545.2222"之类的数字字符串解析为相应的浮点值542.2222?或者将字符串"31"解析为整数,31?


我只想知道如何解析 float stringfloat,以及(单独)将 int string解析为int

最佳参考


>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

其它参考1


def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

其它参考2


检查字符串是否为float的Python方法:



def isfloat(value):
  try:
    float(value)
    return True
  except:
    return False


此功能的更长,更准确的名称可能是:isConvertibleToFloat(value)


什么是,而不是Python中的浮点数可能会让你感到惊讶:



val                   isfloat(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad


你认为你知道什么数字?你没有想象的那么好!没什么大惊喜。[70]

其它参考3


这是另一种值得在此提及的方法,ast.literal_eval:[71]



  这可用于安全地评估包含来自不受信任来源的Python表达式的字符串,而无需自己解析值。



也就是说,一个安全的评估


>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31

其它参考4


float(x) if '.' in x else int(x)

其它参考5


本地化和逗号



您应该考虑数字的字符串表示中逗号的可能性,例如float("545,545.2222")引发异常的情况。相反,使用locale中的方法将字符串转换为数字并正确解释逗号。一旦为所需的数字约定设置了语言环境,locale.atof方法就会在一步中转换为浮点数。


示例1 - 美国号码惯例


在美国和英国,逗号可以用作千位分隔符。在使用美国语言环境的此示例中,逗号作为分隔符正确处理:


>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>


示例2 - 欧洲号码惯例


在世界上大多数国家/地区,逗号用于十进制标记而不是句点。在具有法语区域设置的此示例中,逗号被正确处理为小数点:[72]


>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222


方法locale.atoi也可用,但参数应该是整数。

其它参考6


用户 codelogic 和 harley 是正确的,但请记住,如果您知道该字符串是一个整数(例如,545),您可以先调用int(545)铸造漂浮。


如果您的字符串在列表中,您也可以使用map函数。


>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>


如果它们完全相同,那就好了。

其它参考7


如果你不反对第三方模块,你可以查看fastnumbers模块。它提供了一个名为fast_real的函数,它完全符合这个问题的要求,并且比纯Python实现更快:[73]]] [74]


>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int

其它参考8



  在Python中,如何将像545.2222这样的数字字符串解析为相应的浮点值542.2222?或者将字符串31解析为整数,31?
  我只想知道如何将浮点字符串解析为float,并(单独)将int字符串解析为int。



你要求分别做这些事情是件好事。如果你把它们混合起来,你可能会在以后为自己找到问题。简单的答案是:


"545.2222"浮动:


>>> float("545.2222")
545.2222


"31"为整数:


>>> int("31")
31


其他转换,来自字符串和文字的内容:



各种基础的转换,你应该提前知道基数(默认为10)。请注意,您可以使用Python期望的文字前缀(参见下文)或删除前缀:


>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31


如果您事先不知道基数,但是您确实知道它们将具有正确的前缀,那么如果您将0作为基数,Python可以为您推断:


>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31


来自其他基地的非十进制(即整数)文字



如果您的动机是让您自己的代码清楚地表示硬编码的特定值,那么您可能不需要从基础转换 - 您可以让Python使用正确的语法自动执行此操作。


您可以使用apropos前缀自动转换为具有以下文字的整数。这些对Python 2和3有效:[75]


二进制,前缀0b


>>> 0b11111
31


八进制,前缀0o


>>> 0o37
31


十六进制,前缀0x


>>> 0x1f
31


这在描述二进制标志,代码中的文件权限或颜色的十六进制值时非常有用 - 例如,请注意没有引号:


>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215


使不明确的Python 2 octals与Python 3兼容



如果你看到一个以0开头的整数,在Python 2中,这是(不推荐的)八进制语法。


>>> 037
31


这很糟糕,因为看起来价值应该是37。所以在Python 3中,它现在提出了SyntaxError:


>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token


使用0o前缀将Python 2八进制转换为在2和3中都有效的八进制:


>>> 0o37
31

其它参考9


这个问题似乎有点老了。但是,让我建议一个函数,parseStr,它使类似的东西,即返回整数或浮点数,如果给定的ASCII字符串不能转换为它们中的任何一个,它返回它不受影响。当然代码可以调整为只做你想要的:


   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
   ...                      int(x) or x.isalnum() and x or \
   ...                      len(set(string.punctuation).intersection(x)) == 1 and \
   ...                      x.count('.') == 1 and float(x) or x
   >>> parseStr('123')
   123
   >>> parseStr('123.3')
   123.3
   >>> parseStr('3HC1')
   '3HC1'
   >>> parseStr('12.e5')
   1200000.0
   >>> parseStr('12$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'

其它参考10


float("545.2222")int(float("545.2222"))

其它参考11


YAML解析器可以帮助您确定字符串的数据类型。使用yaml.load(),然后您可以使用type(result)测试类型:[76]


>>> import yaml

>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>

>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>

>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>

其它参考12


def get_int_or_float(v):
    number_as_float = float(v)
    number_as_int = int(number_as_float)
    return number_as_int if number_as_float == number_as_int else number_as_float

其它参考13


您需要考虑舍入才能正确执行此操作。


即int(5.1)=> 5
     int(5.6)=> 5 - 错误,应该是6所以我们做int(5.6 + 0.5)=> 6


def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)

其它参考14


def num(s):
"""num(s)
num(3),num(3.7)-->3
num('3')-->3, num('3.7')-->3.7
num('3,700')-->ValueError
num('3a'),num('a3'),-->ValueError
num('3e4') --> 30000.0
"""
try:
    return int(s)
except ValueError:
    try:
        return float(s)
    except ValueError:
        raise ValueError('argument is not a string of number')

其它参考15


我使用这个功能


import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return


它会将字符串转换为其类型


value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float

其它参考16


这是更正后的版本
https://stackoverflow.com/a/33017514/5973334


这将尝试解析字符串并返回intfloat,具体取决于字符串表示的内容。
它可能会导致解析异常或出现意外行为。


  def get_int_or_float(v):
        number_as_float = float(v)
        number_as_int = int(number_as_float)
        return number_as_int if number_as_float == number_as_int else 
        number_as_float

其它参考17


我很惊讶没有人提到正则表达式,因为有时字符串必须在转换为数字之前准备并规范化


import re
def parseNumber(value, as_int=False):
    try:
        number = float(re.sub('[^.\-\d]', '', value))
        if as_int:
            return int(number + 0.5)
        else:
            return number
    except ValueError:
        return float('nan')  # or None if you wish


用法:


parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0


顺便说一句,要验证你有一个数字:


import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal

其它参考18


Python在一个内核中具有很大的解析灵活性。


str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))

其它参考19


要在python中进行类型转换,请使用该类型的构造函数,将字符串(或您尝试转换的任何值)作为参数传递。


例如:


>>>float("23.333")
   23.333


在幕后,python调用对象__float__方法,该方法应该返回参数的浮点表示。这是特别强大的,因为您可以使用__float__方法定义自己的类型(使用类),以便可以使用float(myobject)将其转换为float。

其它参考20


使用:


def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()


这是我能想出的最恐怖的方式。

其它参考21


使用:


>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>

其它参考22


这是对你的问题的另一种解释(提示:它含糊不清)。你可能正在寻找这样的东西:


def parseIntOrFloat( aString ):
    return eval( aString )


它像这样工作......


>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545





从理论上讲,这是一个注入漏洞。例如,字符串可能是"import os; os.abort()"。然而,如果字符串来自哪里没有任何背景,那么可能是理论推测。由于问题含糊不清,所以不是如果这个漏洞确实存在与否,那就清楚了。