如何将字符串解析为浮点数或整数?

2024-11-18 08:40:00
admin
原创
18
摘要:问题描述:我怎样才能将 转换str为float?"545.2222" -> 545.2222 或者str到int?"31" -> 31 对于相反的操作,请参阅在 Python 中将整数转换为字符串和将浮点数转换为字符串而不进行四舍五入。请改用“如何将输入读为...

问题描述:

我怎样才能将 转换strfloat

"545.2222" -> 545.2222

或者strint

"31" -> 31

对于相反的操作,请参阅在 Python 中将整数转换为字符串和将浮点数转换为字符串而不进行四舍五入。

请改用“如何将输入读为数字?”来关闭重复的问题,其中 OP从用户输入中收到一个字符串并立即想要转换它,或者希望input(在 3.x 中)自动转换类型。


解决方案 1:

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

解决方案 2:

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

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

对于 Python3 版本的 is_float,请参阅:检查字符串是否可以在 Python 中转换为浮点数

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

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

以下单元测试是使用 python2 完成的。检查 Python3 对于哪些字符串可转换为浮点数有不同的行为。一个令人困惑的区别是现在允许任意数量的内部下划线: (float("1_3.4") == float(13.4))是 True

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
"    
12
"          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_2_3.4"             False        Underscores not allowed
"12 34"               False        Spaces not allowed on interior
"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 这样的鸭子类型原型语言编写生命攸关的软件,那么您会遇到更大的问题。

解决方案 3:

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

解决方案 4:

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

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

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

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

解决方案 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——欧洲数字惯例

在世界上大多数国家,逗号用作小数点,而不是句号。在这个法语区域设置的例子中,逗号被正确地处理为小数点:

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

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

解决方案 6:

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

解决方案 7:

如果您不反对第三方模块,您可以查看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

解决方案 8:

在 Python 中,如何将数字字符串(如“545.2222”)解析为其对应的浮点值 542.2222?或者将字符串“31”解析为整数 31?
我只想知道如何将浮点字符串解析为浮点数,以及如何(单独)将 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 兼容

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

>>> 037
31

这很糟糕,因为看起来值应该是37。所以在 Python 3 中,它现在引发了一个SyntaxError

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

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

>>> 0o37
31

解决方案 9:

用户codelogicharley是正确的,但请记住,如果您知道字符串是一个整数(例如,545),您可以调用 int("545") 而无需先转换为浮点数。

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

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

只有当它们都是同一类型时才好。

解决方案 10:

这个问题似乎有点老了。但我建议使用一个函数 parseStr,它的作用类似,即返回整数或浮点数,如果给定的 ASCII 字符串无法转换为任何值,则原封不动地返回。当然,代码可能会调整为只执行您想要的操作:

   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \n   ...                      int(x) or x.isalnum() and x or \n   ...                      len(set(string.punctuation).intersection(x)) == 1 and \n   ...                      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'

解决方案 11:

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

解决方案 12:

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

解决方案 13:

我用这个函数来做

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

解决方案 14:

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

解决方案 15:

您可以使用json.loads

>>> import json
>>> json.loads('123.456')
123.456
>>> type(_)
<class 'float'>
>>> 

正如您所见,它变成了一种类型float

解决方案 16:

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

解决方案 17:

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

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

解决方案 18:

还有正则表达式,因为有时在转换为数字之前必须准备并规范化字符串:

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

顺便说一下,有一些东西可以验证你有一个号码:

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

解决方案 19:

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

例如:

>>>float("23.333")
   23.333

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

解决方案 20:

处理十六进制、八进制、二进制、十进制和浮点数

该解决方案将处理所有数字的字符串约定(我所知道的所有)。

def to_number(n):
    ''' Convert any number representation to a number
    This covers: float, decimal, hex, and octal numbers.
    '''

    try:
        return int(str(n), 0)
    except:
        try:
            # Python 3 doesn't accept "010" as a valid octal.  You must use the
            # '0o' prefix
            return int('0o' + n, 0)
        except:
            return float(n)

这个测试用例输出说明了我所说的内容。

======================== CAPTURED OUTPUT =========================
to_number(3735928559)   = 3735928559 == 3735928559
to_number("0xFEEDFACE") = 4277009102 == 4277009102
to_number("0x0")        =          0 ==          0
to_number(100)          =        100 ==        100
to_number("42")         =         42 ==         42
to_number(8)            =          8 ==          8
to_number("0o20")       =         16 ==         16
to_number("020")        =         16 ==         16
to_number(3.14)         =       3.14 ==       3.14
to_number("2.72")       =       2.72 ==       2.72
to_number("1e3")        =     1000.0 ==       1000
to_number(0.001)        =      0.001 ==      0.001
to_number("0xA")        =         10 ==         10
to_number("012")        =         10 ==         10
to_number("0o12")       =         10 ==         10
to_number("0b01010")    =         10 ==         10
to_number("10")         =         10 ==         10
to_number("10.0")       =       10.0 ==         10
to_number("1e1")        =       10.0 ==         10

测试如下:

class test_to_number(unittest.TestCase):

    def test_hex(self):
        # All of the following should be converted to an integer
        #
        values = [

                 #          HEX
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0xDEADBEEF  , 3735928559), # Hex
                ("0xFEEDFACE", 4277009102), # Hex
                ("0x0"       ,          0), # Hex

                 #        Decimals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (100         ,        100), # Decimal
                ("42"        ,         42), # Decimal
            ]



        values += [
                 #        Octals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0o10        ,          8), # Octal
                ("0o20"      ,         16), # Octal
                ("020"       ,         16), # Octal
            ]


        values += [
                 #        Floats
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (3.14        ,       3.14), # Float
                ("2.72"      ,       2.72), # Float
                ("1e3"       ,       1000), # Float
                (1e-3        ,      0.001), # Float
            ]

        values += [
                 #        All ints
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                ("0xA"       ,         10),
                ("012"       ,         10),
                ("0o12"      ,         10),
                ("0b01010"   ,         10),
                ("10"        ,         10),
                ("10.0"      ,         10),
                ("1e1"       ,         10),
            ]

        for _input, expected in values:
            value = to_number(_input)

            if isinstance(_input, str):
                cmd = 'to_number("{}")'.format(_input)
            else:
                cmd = 'to_number({})'.format(_input)

            print("{:23} = {:10} == {:10}".format(cmd, value, expected))
            self.assertEqual(value, expected)

解决方案 21:

将您的字符串传递给此函数:

def string_to_number(str):
  if("." in str):
    try:
      res = float(str)
    except:
      res = str
  elif(str.isdigit()):
    res = int(str)
  else:
    res = str
  return(res)

它将根据传递的内容返回 int、float 或 string。

字符串为 int

print(type(string_to_number("124")))
<class 'int'>

浮点型字符串

print(type(string_to_number("12.4")))
<class 'float'>

字符串,即字符串

print(type(string_to_number("hello")))
<class 'str'>

看起来像浮点数的字符串

print(type(string_to_number("hel.lo")))
<class 'str'>

解决方案 22:

a = int(float(a)) if int(float(a)) == float(a) else float(a)

解决方案 23:

这是龙猫答案的修正版

这将尝试解析一个字符串并返回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

解决方案 24:

如果您正在处理混合整数和浮点数,并且想要一种一致的方式来处理混合数据,那么这是我使用适当的文档字符串的解决方案:

def parse_num(candidate):
    """Parse string to number if possible
    It work equally well with negative and positive numbers, integers and floats.

    Args:
        candidate (str): string to convert

    Returns:
        float | int | None: float or int if possible otherwise None
    """
    try:
        float_value = float(candidate)
    except ValueError:
        return None

    # Optional part if you prefer int to float when decimal part is 0
    if float_value.is_integer():
        return int(float_value)
    # end of the optional part

    return float_value

# Test
candidates = ['34.77', '-13', 'jh', '8990', '76_3234_54']
res_list = list(map(parse_num, candidates))
print('Before:')
print(candidates)
print('After:')
print(res_list)

输出:

Before:
['34.77', '-13', 'jh', '8990', '76_3234_54']

After:
[34.77, -13, None, 8990, 76323454]

解决方案 25:

使用:

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

这是我能想到的最 Python 化的方法。

解决方案 26:

如果您不想使用第三方模块,以下可能是最强大的解决方案:

def string_to_int_or_float(s):
    try:
        f = float(s) # replace s with str(s) if you are not sure that s is a string
    except ValueError:
        print("Provided string '" + s + "' is not interpretable as a literal number.")
        raise
    try:
        i = int(str(f).rstrip('0').rstrip('.'))
    except:
        return f
    return i

它可能不是最快的,但它可以正确处理许多其他解决方案无法处理的文字数字,例如:

>>> string_to_int_or_float('789.')
789
>>> string_to_int_or_float('789.0')
789
>>> string_to_int_or_float('12.3e2')
1230
>>> string_to_int_or_float('12.3e-2')
0.123
>>> string_to_int_or_float('4560e-1')
456
>>> string_to_int_or_float('4560e-2')
45.6

解决方案 27:

这是一个函数,它会根据提供的实际字符串是否类似于或,将任何object(不仅仅是str)转换为int或。此外,如果它是同时具有和方法的对象,则默认使用float int`float__floatint`__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

解决方案 28:

通过使用 int 和 float 方法,我们可以将字符串转换为整数和浮点数。

s="45.8"
print(float(s))

y='67'
print(int(y))

解决方案 29:

对于数字和字符一起:

string_for_int = "498 results should get"
string_for_float = "498.45645765 results should get"

第一次导入

 import re

 # For getting the integer part:
 print(int(re.search(r'd+', string_for_int).group())) #498

 # For getting the float part:
 print(float(re.search(r'd+.d+', string_for_float).group())) #498.45645765

对于简单模型:

value1 = "10"
value2 = "10.2"
print(int(value1)) # 10
print(float(value2)) # 10.2

解决方案 30:

你可以简单地这样做

s = '542.22'

f = float(s) # This converts string data to float data with a decimal point
print(f) 

i = int(f) # This converts string data to integer data by just taking the whole number part of it
print(i) 

有关数据类型解析的更多信息,请查看 Python 文档!

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用