在 Python 中,如何解析数字字符串,例如
"545.2222"
到其对应的浮点值,
545.2222
? 或者将字符串解析为"31"
整数,31
?
我只想知道如何将float str
解析为 a float
,以及(单独)将int str
解析为 an int
。
在 Python 中,如何解析数字字符串,例如
"545.2222"
到其对应的浮点值,
545.2222
? 或者将字符串解析为"31"
整数,31
?
我只想知道如何将float str
解析为 a float
,以及(单独)将int str
解析为 an int
。
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
def is_float(value):
try:
float(value)
return True
except:
return False
此函数的更长更准确的名称可能是:is_convertible_to_float(value)
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 之类的鸭式原型语言编写对生命至关重要的软件,那么您将遇到更大的问题。
def num(s):
try:
return int(s)
except ValueError:
return float(s)
这是另一种值得在这里提及的方法,ast.literal_eval:
这可用于安全地评估来自不受信任来源的包含 Python 表达式的字符串,而无需自己解析值。
也就是说,一个安全的“评估”
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float("545,545.2222")
对于引发异常的情况,您应该考虑在数字的字符串表示中使用逗号的可能性 。相反,使用 in 方法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
也可用,但参数应为整数。
float(x) if '.' in x else int(x)
如果您不反对第三方模块,可以查看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
用户codelogic和harley是正确的,但请记住,如果您知道字符串是整数(例如 545),您可以调用 int("545") 而不首先转换为浮点数。
如果您的字符串在列表中,您也可以使用 map 函数。
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
只有当它们都是同一类型时才好。
在 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
如果你看到一个以 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
这个问题似乎有点老了。但是让我建议一个函数 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'
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')
您需要考虑四舍五入才能正确执行此操作。
即 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
将您的字符串传递给此函数:
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'>
要在 python 中进行类型转换,请使用类型的构造函数,将字符串(或您尝试转换的任何值)作为参数传递。
例如:
>>>float("23.333")
23.333
在幕后,python 正在调用 objects__float__
方法,该方法应该返回参数的浮点表示。这特别强大,因为您可以使用方法定义自己的类型(使用类),__float__
以便可以使用 float(myobject) 将其转换为浮点数。
处理十六进制、八进制、二进制、十进制和浮点数
该解决方案将处理数字的所有字符串约定(我所知道的一切)。
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)
a = int(float(a)) if int(float(a)) == float(a) else float(a)
你可以使用json.loads
:
>>> import json
>>> json.loads('123.456')
123.456
>>> type(_)
<class 'float'>
>>>
如您所见,它变成了float
.
这是 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 的方式。
这是一个老问题,已经得到了很多答案。但是,如果您正在处理混合整数和浮点数并且想要一种一致的方式来处理您的混合数据,这是我使用正确文档字符串的解决方案:
def parse_num(candidate):
"""parse string to number if possible
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]
采用:
>>> 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'>
这是一个函数,它将根据提供的实际字符串是否类似于or将任何object
(不仅仅是str
)转换为int
or 。此外,如果它是同时具有和方法的对象,则默认为使用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
对于数字和字符一起:
string_for_int = "498 results should get"
string_for_float = "498.45645765 results should get"
首先导入重新:
import re
#for get integer part:
print(int(re.search(r'\d+', string_for_int).group())) #498
#for get 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
通过使用 int 和 float 方法,我们可以将字符串转换为整数和浮点数。
s="45.8"
print(float(s))
y='67'
print(int(y))
这是对您的问题的另一种解释(提示:含糊不清)。您可能正在寻找这样的东西:
def parseIntOrFloat( aString ):
return eval( aString )
它像这样工作......
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
理论上,存在注入漏洞。例如,字符串可以是"import os; os.abort()"
. 然而,在没有任何关于字符串来自何处的背景的情况下,这种可能性是理论上的推测。由于问题含糊不清,因此根本不清楚该漏洞是否真的存在。