如何在Python中将字符串解析为float或int?

时间:2008-12-19 01:52:26

标签: python parsing floating-point type-conversion integer

在Python中,如何将"545.2222"之类的数字字符串解析为相应的浮点值545.2222?或者将字符串"31"解析为整数31

我只是想知道如何将 float str解析为float,以及(另外)解析 int {{1}到str

32 个答案:

答案 0 :(得分:2359)

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

答案 1 :(得分:476)

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

答案 2 :(得分:465)

检查字符串是否为float的Python方法:

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

此功能的更长更准确的名称可以是:is_convertible_to_float(value)

什么是Python并且不是{{3}}中的浮动可能会让您感到惊讶:

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

你认为你知道什么是数字?你没有想象的那么好!不出意外。

请勿在生命关键型软件上使用此代码!

以这种方式捕获广泛的异常,杀死金丝雀并吞噬异常会产生一个很小的机会,即有效的float as string将返回false。 float(...)代码行可能因为与字符串内容无关的一千个原因中的任何一个而失败。但是如果你用像Python这样的鸭子原型语言编写生命关键型软件,那么你就会遇到更大的问题。

答案 3 :(得分:115)

这是另一种值得在此提及的方法,ast.literal_eval

  

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

即安全'评估'

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

答案 4 :(得分:76)

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

答案 5 :(得分:58)

本地化和逗号

对于像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 - 欧洲号码惯例

majority of countries of the world中,逗号用于十进制标记而不是句点。在具有法语区域设置的此示例中,逗号被正确处理为小数点:

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

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

答案 6 :(得分:23)

用户 codelogic harley 是正确的,但请记住,如果您知道字符串是整数(例如,545),则可以调用int(“545”没有先铸造漂浮。

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

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

如果它们的类型相同,那就好了。

答案 7 :(得分:23)

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

问题似乎有点老了。但是,让我建议一个函数,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'

答案 9 :(得分:18)

  

在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

如果你事先不知道基数,但是你知道它们会有正确的前缀,那么如果你以0为基数,Python可以为你推断出这个:

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

来自其他基地的非十进制(即整数)文字

如果您的动机是让您自己的代码清楚地表示硬编码的特定值,那么您可能不需要从基础转换 - 您可以让Python使用正确的语法自动为您执行此操作。

您可以使用apropos前缀自动转换为the following literals的整数。这些对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 octals与Python 3

兼容

如果你看到一个以0开头的整数,在Python 2中,这是(不推荐的)八进制语法。

>>> 037
31

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

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

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

>>> 0o37
31

答案 10 :(得分:15)

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

答案 11 :(得分:13)

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

答案 12 :(得分: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

答案 13 :(得分:11)

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 :(得分:8)

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

答案 15 :(得分:6)

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

即。 int(5.1)=&gt;五      int(5.6)=&gt; 5 - 错误,应该是6所以我们做int(5.6 + 0.5)=&gt; 6

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

答案 16 :(得分: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

答案 17 :(得分:4)

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

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

答案 18 :(得分:4)

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

例如:

>>>float("23.333")
   23.333

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

答案 19 :(得分:3)

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

这将尝试解析字符串并返回intfloat,具体取决于字符串表示的内容。 它可能会解析异常或have some unexpected behaviour

  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

答案 20 :(得分:2)

您可以使用str()将任何变量转换为字符串,使用int()将字符串整数转换为整数,并使用float()将字符串浮点数转换为浮点值。

str_to_float = float("545.2222")
str_to_int = int("31")

答案 21 :(得分:1)

使用:

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

这是我能想出的最恐怖的方式。

答案 22 :(得分:0)

这是一个老问题,已经有很多答案了。 但如果您正在处理混合整数和浮点数,并希望以一致的方式处理混合数据,这里是我的解决方案,其中包含适当的文档字符串:

SELECT price,(SELECT price FROM uri WHERE price IN ('25.50'))From uri
WHERE price IN ('800');

输出:

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)

答案 23 :(得分:0)

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

答案 24 :(得分:0)

将数字和字符一起使用:

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

答案 25 :(得分:0)

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

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。

为整数的字符串

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

答案 26 :(得分:0)

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

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

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)

答案 27 :(得分:0)

这是一个函数,它将根据提供的实际字符串是否看起来像object(而不仅仅是str)转换为intfloatintfloat __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 方法的对象,则默认使用### wrong source_arn = "${aws_api_gateway_deployment.deployment_test.execution_arn}/*/*" ### correct source_arn = "${aws_api_gateway_rest_api.rest_api_test.execution_arn}/*/*"

class GuestViewController: UITableViewController {
var rows:[[[String:Any]]] = [[["type":RowType.DetailContent,
                               "subType":DCType.DCRightContent,
                               "name":CPFFields.CID,
                               "content":"9637"],                                  
                             ["type":RowType.DetailContent,
                              "subType":DCType.DCInput,
                              "name":CPFFields.VISIA]],

                             [["type":RowType.DetailTextView,
                               "CPFType":CPFFields.UV,
                               "title":CPFFields.preferenceTitle]],

                             [["type":RowType.DetailContent,
                               "subType":DCType.DCSelection,
                               "name":CPFFields.Phototherapy,
                               "title":CPFFields.anestheticTitle],
                              ["type":RowType.DetailTextView,
                               "CPFType":CPFFields.Phototherapy,
                               "title":CPFFields.preferenceTitle]],                                 
                             ]
var isNewGuestSelected : Bool = false

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  

    return rows[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let item = rows[indexPath.section][indexPath.row]     

    let type = item["type"] as! RowType

    if type == RowType.DetailContent
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DetailNameCell", for: indexPath) as! DetailContentCell

        let cpfType = item["name"] as? CPFFields ?? .Customer
        cell.name.text = CPFFields.localizedString(from: cpfType)
        if let field = item["title"] as? CPFFields
        {
            cell.name.text = CPFFields.localizedString(from: field)
        }
        cell.moreSlectionLeftSpace = true

        var content:String? = ""
        cell.type = cpfType
        switch cpfType {
        case .CID:
            content = (profile?.birthDate.dateFromDateString?.stringForPaitentId ?? "") + (profile?.name ?? "")
        case .CT:
            content = ""
            if let profile = profile
            {
                content = CPFCustomerType.localizedString(from: profile.type)
                //New Guest
                if(content == CPFCustomerType.type1.rawValue){

                    rows[0].insert(["type":RowType.DetailContent,
                                    "subType":DCType.DCRightContent,
                                    "name":CPFFields.CID,
                                    "content":"9637"], at: 1)
                    isNewGuestSelected = true

                } else{
                    if isNewGuestSelected == true{
                        rows[0].remove(at: 1)
                        isNewGuestSelected = false
                    }
                }
            }


let subType = item["subType"] as! DCType
            cell.setcontentType(type: subType, content: content)
            return cell
    }

I expected not to see "rows[0][2]" after running "rows[0].remove(at:1)".
However the log is printing
    rows[0][0]
    rows[0][1]
    rows[0][2]        
    then 
    it crashed at "let item = rows[indexPath.section][indexPath.row]"
    because it is out of range

答案 28 :(得分:0)

使用:

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

答案 29 :(得分:-2)

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

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

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

答案 30 :(得分:-4)

代替考虑评估,可以使用以下方法解决问题

if '.' in string:
    print(float(string))
else:
    print(int(string))

try-except也可以用作替代方法。尝试在try块中将字符串转换为int。如果该字符串是浮点值,它将抛出一个错误,该错误将被捕获在except块中,例如

try:
    print(int(string))
except:
    print(float(string))

答案 31 :(得分:-9)

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

def parseIntOrFloat( aString ):
    return eval( aString )

就像这样......

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

理论上,存在注射漏洞。例如,字符串可以是"import os; os.abort()"。然而,没有关于字符串来自何处的任何背景,可能是理论推测。由于问题含糊不清,如果这个漏洞确实存在与否,则一点也不清楚。