如何将字符串解析为 float 或 int?

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

我只是想知道如何解析 strfloat ,以及(分别)一个int strint

答案

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

检查字符串是否为浮点数的 Python 方法:

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

此函数的更长更准确的名称可能是: is_convertible_to_float(value)

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

val                   is_float(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

您以为知道什么数字?你不像你想的那样好!并不奇怪。

不要在对生命至关重要的软件上使用此代码!

用这种方式捕获广泛的异常,杀死金丝雀和吞噬异常会产生很小的机会,即有效的 float 字符串将返回 false。代码的float(...)行可能由于数千种与字符串内容无关的原因而失败。但是,如果您正在使用像 Python 这样的鸭子式原型语言来编写至关重要的软件,那么您将遇到更大的问题。

这是另一个值得一提的方法ast.literal_eval

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

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

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)

本地化和逗号

您应该考虑数字的字符串表示形式中可能出现逗号的情况,例如对于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 - 欧洲数字约定

在世界上大多数国家 / 地区 ,逗号用于小数点而不是句点。在此使用法语语言环境的示例中,逗号被正确处理为小数点:

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

也可以使用方法locale.atoi ,但参数应为整数。

如果您不喜欢第三方模块,则可以签出fastnumbers模块。它提供了一个名为fast_real的函数,该函数可以完全满足此问题的要求,并且比纯 Python 实现要快:

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

用户codelogicharley是正确的,但是请记住,如果您知道字符串是整数(例如 545),则可以调用 int(“545”)而不先进行浮点运算。

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

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

只有它们都是相同的类型才是好。

这个问题似乎有点老了。但是让我建议一个函数 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'

在 Python 中,如何将 “545.2222” 之类的数字字符串解析为其对应的浮点值 542.2222?还是将字符串 “31” 解析为整数 31?我只想知道如何将 float 字符串解析为 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 有效:

二进制,前缀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 八进制与 Python 3 兼容

如果您在 Python 2 中看到一个以 0 开头的整数,则这是(不建议使用的)八进制语法。

>>> 037
31

这很糟糕,因为看起来值应该为37 。因此,在 Python 3 中,它现在引发SyntaxError

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

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

>>> 0o37
31