如何在Python中解析字符串到浮点数或整数?

[英]How do I parse a string to a float or int in Python?


In Python, how can I parse a numeric string like "545.2222" to its corresponding float value, 542.2222? Or parse the string "31" to an integer, 31?

在Python中,我如何解析一个数字字符串,比如“545.2222”,它对应的浮点值是542.2222?或者将字符串“31”解析为整数,31?

I just want to know how to parse a float string to a float, and (separately) an int string to an int.

我只想知道如何将浮点字符串解析为浮点数,并(单独地)将int字符串解析为int。

22 个解决方案

#1


1962  

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

#2


432  

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

#3


390  

Python method to check if a string is a float:

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

A longer and more accurate name for this function could be: isConvertibleToFloat(value)

这个函数的一个更长的、更准确的名称可以是:isConvertibleToFloat(值)

What is, and is not a float in Python may surprise you:

val                   isfloat(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         Hexidecimal
"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

You think you know what numbers are? You are not so good as you think! Not big surprise.

你知道数字是什么吗?你不像你想的那么好!没有大的惊喜。

#4


103  

This is another method which deserves to be mentioned here, ast.literal_eval:

这是另一个值得在这里提到的方法。

This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.

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

That is, a safe 'eval'

这是一个安全的" eval "

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

#5


71  

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

#6


41  

Localization and commas

You should consider the possibility of commas in the string representation of a number, for cases like float("545,545.2222") which throws an exception. Instead, use methods in locale to convert the strings to numbers and interpret commas correctly. The locale.atof method converts to a float in one step once the locale has been set for the desired number convention.

您应该考虑在一个数字的字符串表示中使用逗号的可能性,比如float(“545,545.2222”),它会抛出异常。相反,在locale中使用方法将字符串转换为数字,并正确解释逗号。语言环境。atof方法在设置为所需的数字约定的区域设置后,在一个步骤中转换为浮点数。

Example 1 -- United States number conventions

示例1——美国的数字约定。

In the United States and the UK, commas can be used as a thousands separator. In this example with American locale, the comma is handled properly as a separator:

在美国和英国,逗号可以用作数千个分隔符。在这个带有美国语言环境的例子中,逗号作为分隔符正确处理:

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

Example 2 -- European number conventions

示例2——欧洲数字约定。

In the majority of countries of the world, commas are used for decimal marks instead of periods. In this example with French locale, the comma is correctly handled as a decimal mark:

在世界上大多数国家,用逗号代替句号。在这个法语地区的例子中,逗号被正确地处理为十进制标记:

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

The method locale.atoi is also available, but the argument should be an integer.

语言环境的方法。atoi也可用,但是参数应该是整数。

#7


20  

Users codelogic and harley are correct, but keep in mind if you know the string is an integer (for example, 545) you can call int("545") without first casting to float.

用户codelogic和harley是正确的,但是请记住,如果您知道字符串是一个整数(例如,545),您可以调用int(“545”),而不需要先进行浮动。

If your strings are in a list, you could use the map function as well.

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

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

It is only good if they're all the same type.

如果它们都是同一类型的,那就更好了。

#8


19  

If you aren't averse to third-party modules, you could check out the fastnumbers module. It provides a function called fast_real that does exactly what this question is asking for and does it faster than a pure-Python implementation:

如果您不反对第三方模块,您可以查看fastnumbers模块。它提供了一个名为fast_real的函数,它能准确地完成这个问题的要求,并且比pure-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

#9


16  

In Python, how can I parse a numeric string like "545.2222" to its corresponding float value, 542.2222? Or parse the string "31" to an integer, 31? I just want to know how to parse a float string to a float, and (separately) an int string to an int.

在Python中,我如何解析一个数字字符串,比如“545.2222”,它对应的浮点值是542.2222?或者将字符串“31”解析为整数,31?我只想知道如何将浮点字符串解析为浮点数,并(单独地)将int字符串解析为int。

It's good that you ask to do these separately. If you're mixing them, you may be setting yourself up for problems later. The simple answer is:

你要求分开做,这很好。如果你把它们混在一起,你可能会在以后的问题中遇到麻烦。简单的答案是:

"545.2222" to float:

“545.2222”浮动:

>>> float("545.2222")
545.2222

"31" to an integer:

“31”一个整数:

>>> int("31")
31

Other conversions, ints to and from strings and literals:

Conversions from various bases, and you should know the base in advance (10 is the default). Note you can prefix them with what Python expects for its literals (see below) or remove the prefix:

从不同的基地转换,你应该提前知道基地(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

If you don't know the base in advance, but you do know they will have the correct prefix, Python can infer this for you if you pass 0 as the base:

如果你事先不知道底数,但你知道它们的前缀是正确的,如果你以0作为基数,Python可以推断出这一点:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

Non-Decimal (i.e. Integer) Literals from other Bases

If your motivation is to have your own code clearly represent hard-coded specific values, however, you may not need to convert from the bases - you can let Python do it for you automatically with the correct syntax.

如果您的动机是让您自己的代码清楚地代表硬编码的特定值,但是,您可能不需要从基础转换—您可以让Python自动地使用正确的语法来完成它。

You can use the apropos prefixes to get automatic conversion to integers with the following literals. These are valid for Python 2 and 3:

您可以使用apropos前缀来自动转换为整数,并使用以下文字。这些对于Python 2和3是有效的:

Binary, prefix 0b

二进制,前缀0 b

>>> 0b11111
31

Octal, prefix 0o

八进制,前缀0 o

>>> 0o37
31

Hexadecimal, prefix 0x

十六进制,前缀0 x

>>> 0x1f
31

This can be useful when describing binary flags, file permissions in code, or hex values for colors - for example, note no quotes:

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

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

Making ambiguous Python 2 octals compatible with Python 3

If you see an integer that starts with a 0, in Python 2, this is (deprecated) octal syntax.

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

>>> 037
31

It is bad because it looks like the value should be 37. So in Python 3, it now raises a SyntaxError:

这很糟糕,因为它的值应该是37。所以在Python 3中,它提出了一个SyntaxError:

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

Convert your Python 2 octals to octals that work in both 2 and 3 with the 0o prefix:

将您的Python 2 octals转换为octals,在2和3中都使用0o前缀:

>>> 0o37
31

#10


14  

The question seems a little bit old. But let me suggest a function, parseStr, which makes something similar, that is, returns integer or float and if a given ASCII string cannot be converted to none of them it returns it untouched. The code of course might be adjusted to do only what you want:

这个问题似乎有点过时了。但是让我建议一个函数,parseStr,它使一些类似的东西,也就是返回整数或浮点数,如果一个给定的ASCII字符串不能转换为none,它就不会返回它。当然,代码可以调整为只做你想要的:

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

#11


12  

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

浮动(" 545.2222 ")和int(浮动(" 545.2222 "))

#12


11  

The YAML parser can help you figure out what datatype your string is. Use yaml.load(), and then you can use type(result) to test for type:

YAML解析器可以帮助您确定字符串的数据类型。使用yaml.load(),然后可以使用类型(结果)来测试类型:

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


10  

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

#14


7  

You need to take into account rounding to do this properly.

你需要考虑到四舍五入来做这件事。

I.e. int(5.1) => 5 int(5.6) => 5 -- wrong, should be 6 so we do int(5.6 + 0.5) => 6

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

#15


7  

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

#16


5  

I use this function for that

我用这个函数。

import ast

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

It will convert the string to its type

它将把字符串转换为它的类型。

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

#17


3  

This is a corrected version of https://stackoverflow.com/a/33017514/5973334

这是https://stackoverflow.com/a/33017514/5973334的更正版本。

This will try to parse a string and return either int or float depending on what the string represents. It might rise parsing exceptions or have some unexpected behaviour.

这将尝试解析一个字符串,并根据字符串表示的内容返回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

#18


3  

I am surprised nobody mentioned regex because sometimes string must be prepared and normalized before casting to number

我很惊讶没有人提到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 number
    except ValueError:
        return float('nan')  # or None if you wish

usage:

用法:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

and by the way, something to verify you have a number:

顺便说一下,要验证一下你有一个数字

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

#19


2  

Python have this great flexibility of parsing in one liners.

Python在一个行中具有很大的解析灵活性。

str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))

#20


1  

Use:

使用:

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

This is the most Pythonic way I could come up with.

这是我能想到的最复杂的方法。

#21


0  

Use:

使用:

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

#22


-12  

Here's another interpretation of your question (hint: it's vague). It's possible you're looking for something like this:

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

def parseIntOrFloat( aString ):
    return eval( aString )

It works like this...

是这样的……

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

Theoretically, there's an injection vulnerability. The string could, for example be "import os; os.abort()". Without any background on where the string comes from, however, the possibility is theoretical speculation. Since the question is vague, it's not at all clear if this vulnerability actually exists or not.

从理论上讲,存在注入漏洞。例如,字符串可以是“导入操作系统;os.abort()”。然而,没有任何背景,弦的来源,然而,可能性是理论推测。由于这个问题是模糊的,所以不清楚这个漏洞是否存在。

关注微信公众号

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2008/12/19/8c11ac6eed30c2734538352a4490dc30.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com