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

  • 如何将str转换为float
    "545.2222"  →  545.2222
  • 如何将str转换为int
    "31"        →  31

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

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

4612146 次浏览

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

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

用户编码哈雷是正确的,但请记住,如果您知道字符串是整数(例如545),您可以调用int(“545”)而无需首先转换为浮点数。

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

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

这是好的,如果他们都是相同的类型。

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

def parseIntOrFloat( aString ):return eval( aString )

它是这样工作的…

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

理论上,存在注入漏洞。例如,字符串可能是"import os; os.abort()"。然而,在没有任何关于字符串来自哪里的背景的情况下,这种可能性是理论上的猜测。由于问题含糊不清,因此根本不清楚此漏洞是否真的存在。

def num(s):try:return int(s)except ValueError:return float(s)
float(x) if '.' in x else int(x)

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

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

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

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

这是另一个值得在这里提到的方法,ast.literal_eval

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

这是一个安全的“评估”

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

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

>>> import yaml
>>> a = "545.2222">>> result = yaml.load(a)>>> result545.22220000000004>>> type(result)<type 'float'>
>>> b = "31">>> result = yaml.load(b)>>> result31>>> type(result)<type 'int'>
>>> c = "HI">>> result = yaml.load(c)>>> result'HI'>>> type(result)<type 'str'>

本地化和逗号

您应该考虑在数字的字符串表示形式中使用逗号的可能性,例如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也可用,但参数应该是整数。

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

def is_float(value):if value is None:return Falsetry:float(value)return Trueexcept:return False

对于is_float的Python3版本,请参阅:检查是否可以在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 stringTrue                  True         Pure sweet Truth"True"                False        Vile contemptible lieFalse                 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_2_3.4"             False        Underscores not allowed"12 34"               False        Spaces not allowed on interior"1,234"               False        Commas gtfou'\x30'               True         Unicode is fine."NULL"                False        Null is not special0x3fade               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 allowedu'四'                 False        Japanese '4' is not a float."#56"                 False        Pound sign"56%"                 False        Percent of what?"0E0"                 True         Exponential, move dot 0 places0**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这样的鸭子类型原型语言编写生命关键软件,那么你就会遇到更大的问题。

如果你不反对第三方模块,你可以查看快数模块。它提供了一个名为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

在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

>>> 0b1111131

八进制,前缀0o

>>> 0o3731

十六进制,前缀0x

>>> 0x1f31

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

>>> 0b10101 # binary flags21>>> 0o755 # read, write, execute perms for owner, read & ex for group & others493>>> 0xffffff # the color, white, max values for red, green, and blue16777215

使模棱两可的Python 2八进制与Python 3兼容

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

>>> 03731

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

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

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

>>> 0o3731
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)-->3num('3')-->3, num('3.7')-->3.7num('3,700')-->ValueErrornum('3a'),num('a3'),-->ValueErrornum('3e4') --> 30000.0"""try:return int(s)except ValueError:try:return float(s)except ValueError:raise ValueError('argument is not a string of number')

用途:

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

用途:

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的方式。

这是一个修正版本龙猫的回答

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

我用这个功能

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

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

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

还有regex,因为有时字符串在转换为数字之前必须准备和规范化:

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 numberexcept 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 numbersdef is_number(value):return isinstance(value, numbers.Number)# Will work with int, float, long, Decimal

对于Python中的typecast,使用该类型的构造函数,将字符串(或您尝试转换的任何值)作为参数传递。

例如:

>>>float("23.333")23.333

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

这是一个将任何object(不仅仅是str)转换为intfloat的函数,基于实际字符串是否提供看起来像intfloat。此外,如果它是一个同时具有__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 = Trueelif isinstance(x, str):is_str = True
is_other = not any([is_num, is_str])
if is_num:res = xelif is_str:is_float, is_int, is_char = [False]*3try:res = float(x)if '.' in x:is_float = Trueelse:is_int = Trueexcept ValueError:res = xis_char = True
else:if num_type == 'asis':funcs = [int, float]else:funcs = [num_type]
for func in funcs:try:res = func(x)breakexcept TypeError:continueelse:res = x

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

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

def to_number(n):''' Convert any number representation to a numberThis 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' prefixreturn int('0o' + n, 0)except:return float(n)

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

======================== CAPTURED OUTPUT =========================to_number(3735928559)   = 3735928559 == 3735928559to_number("0xFEEDFACE") = 4277009102 == 4277009102to_number("0x0")        =          0 ==          0to_number(100)          =        100 ==        100to_number("42")         =         42 ==         42to_number(8)            =          8 ==          8to_number("0o20")       =         16 ==         16to_number("020")        =         16 ==         16to_number(3.14)         =       3.14 ==       3.14to_number("2.72")       =       2.72 ==       2.72to_number("1e3")        =     1000.0 ==       1000to_number(0.001)        =      0.001 ==      0.001to_number("0xA")        =         10 ==         10to_number("012")        =         10 ==         10to_number("0o12")       =         10 ==         10to_number("0b01010")    =         10 ==         10to_number("10")         =         10 ==         10to_number("10.0")       =       10.0 ==         10to_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)

将字符串传递给此函数:

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

它将返回int、浮点数或字符串,具体取决于传递的内容。

字符串是一个int

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

字符串是一个浮动

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

String是一个字符串

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

看起来像花车的绳子

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

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

s="45.8"print(float(s))
y='67'print(int(y))

对于数字和字符一起:

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)) # 10print(float(value2)) # 10.2
a = int(float(a)) if int(float(a)) == float(a) else float(a)

如果您正在处理混合整数和浮点数,并希望以一致的方式处理混合数据,以下是我的解决方案,正确的docstring

def parse_num(candidate):"""Parse string to number if possibleIt 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 0if float_value.is_integer():return int(float_value)# end of the optional part
return float_value
# Testcandidates = ['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]

您可以使用json.loads

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

如您所见,它成为float的一种类型。

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

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 stringexcept ValueError:print("Provided string '" + s + "' is not interpretable as a literal number.")raisetry:i = int(str(f).rstrip('0').rstrip('.'))except:return freturn 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

你可以简单地这样做

s = '542.22'
f = float(s) # This converts string data to float data with a decimal pointprint(f)
i = int(f) # This converts string data to integer data by just taking the whole number part of itprint(i)

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