在Python中,如何解析数字字符串,例如 "545.2222" 为其相应的浮点值, 545.2222?或者解析字符串 "31" 为一个整数, 31?

我只是想知道如何解析 漂浮 str 到一个 float, ,和(分别)一个 整数 str 到一个 int.

有帮助吗?

解决方案

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

你认为你知道数字是什么吗?你并没有你想象的那么好!没什么大惊喜。

不要在危及生命的软件上使用此代码!

通过这种方式捕获广泛的异常,杀死金丝雀并吞噬异常会产生一个很小的机会,即有效的浮点数作为字符串返回 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 也可用,但参数应该是整数。

如果您不反对第三方模块,您可以查看 快速数字 模块。它提供了一个名为 快速真实 这正是这个问题所要求的,并且比纯 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

用户 代码逻辑哈雷 是正确的,但请记住,如果您知道字符串是整数(例如 545),则可以调用 int("545"),而无需先转换为 float。

如果您的字符串在列表中,您也可以使用 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

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

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

使用以下命令将 Python 2 八进制转换为可在 2 和 3 中使用的八进制 0o 字首:

>>> 0o37
31

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

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

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

我用这个函数来实现这个目的

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

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

IE。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)

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

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

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

例如:

>>>float("23.333")
   23.333

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

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

这将尝试解析字符串并返回 int 或者 float 取决于字符串代表什么。它可能会引发解析异常或 有一些意想不到的行为.

  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

使用:

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

这是我能想到的最Pythonic 的方法。

使用:

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

这是一个可以转换任何内容的函数 object (不只是 str) 到 int 或者 float, ,基于是否提供了实际的字符串 好像 int 或者 float. 。此外,如果它是一个同时具有两者的对象 __float__int__ 方法,默​​认使用 __float__

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x

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

def parseIntOrFloat( aString ):
    return eval( aString )

它的工作原理是这样的...

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

理论上,存在注入漏洞。例如,该字符串可以是 "import os; os.abort()". 。然而,在没有任何关于字符串来自何处的背景的情况下,这种可能性只是理论上的推测。由于问题很模糊,因此根本不清楚这个漏洞是否确实存在。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top