问题:如何将字符串解析为float或int?

在Python中,如何解析类似于"545.2222"其对应的float值的数字字符串545.2222?还是将字符串解析为"31"整数31

我只是想知道如何分析一个浮动 strfloat,和(单独)的INT strint

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

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


回答 0

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

回答 1

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

回答 2

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

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

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

什么是Python中的浮点数,哪些不是浮点数,可能会让您感到惊讶:

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字符串将返回false。该float(...)行代码可以失败的任何什么都没有做的字符串的内容一千个理由。但是,如果您使用Python这样的鸭子式原型语言来编写至关重要的软件,那么您将遇到更大的问题。

Python method to check if a string is a float:

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

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

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

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

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

Don’t use this code on life-critical software!

Catching broad exceptions this way, killing canaries and gobbling the exception creates a tiny chance that a valid float as string will return false. The float(...) line of code can failed for any of a thousand reasons that have nothing to do with the contents of the string. But if you’re writing life-critical software in a duck-typing prototype language like Python, then you’ve got much larger problems.


回答 3

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

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

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

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

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.

That is, a safe ‘eval’

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

回答 4

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

回答 5

本地化和逗号

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

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.

Example 1 — United States number conventions

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

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.


回答 6

如果您不喜欢第三方模块,则可以签出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

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:

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

回答 7

用户codelogicharley是正确的,但是请记住,如果您知道字符串是整数(例如545),则可以调用int(“ 545”)而不先进行浮点运算。

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

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

只有它们都是相同的类型才是好的。

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.

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

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

在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前缀自动转换为具有以下文字的整数。这些对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兼容

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

>>> 037
31

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

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

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

>>> 0o37
31

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.

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:

>>> float("545.2222")
545.2222

"31" to an integer:

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

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

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

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

Binary, prefix 0b

>>> 0b11111
31

Octal, prefix 0o

>>> 0o37
31

Hexadecimal, prefix 0x

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

>>> 037
31

It is bad because it looks like the value should be 37. So in Python 3, it now raises a 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:

>>> 0o37
31

回答 9

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

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:

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

回答 10

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

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


回答 11

我为此使用此功能

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

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

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

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:

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

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

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

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

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

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

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

回答 16

我很惊讶没有人提到正则表达式,因为有时必须在转换为数字之前准备好字符串并对其进行规范化

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

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

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

回答 17

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

例如:

>>>float("23.333")
   23.333

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

To typecast in python use the constructor funtions of the type, passing the string (or whatever value you are trying to cast) as a parameter.

For example:

>>>float("23.333")
   23.333

Behind the scenes, python is calling the objects __float__ method, which should return a float representation of the parameter. This is especially powerful, as you can define your own types (using classes) with a __float__ method so that it can be casted into a float using float(myobject).


回答 18

这是一个正确版本https://stackoverflow.com/a/33017514/5973334

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

This is a corrected version of 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.

  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

回答 19

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

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

Pass your string to this function:

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)

It will return int, float or string depending on what was passed.

string that is an int

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

string that is a float

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

string that is a string

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

string that looks like a float

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

回答 20

采用:

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

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

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

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

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)

Handles hex, octal, binary, decimal, and float

This solution will handle all of the string conventions for numbers (all that I know about).

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)

This test case output illustrates what I’m talking about.

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

Here is the test:

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)

回答 22

采用:

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

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

回答 23

这是将转换任何一个函数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 = 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

This is a function which will convert any object (not just str) to int or float, based on if the actual string supplied looks like int or float. Further if it’s an object which has both __float and __int__ methods, it defaults to using __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

回答 24

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

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

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

By using int and float methods we can convert a string to integer and floats.

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

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

回答 25

eval()是这个问题的很好解决方案。它不需要检查数字是int还是float,它只给出相应的等价物。如果需要其他方法,请尝试

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

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

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

eval() is a very good solution to this question. It doesn’t need to check if the number is int or float, it just gives the corresponding equivalent. If other methods are required, try

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

try-except can also be used as an alternative. Try converting string to int inside the try block. If the string would be a float value, it will throw an error which will be catched in the except block, like this

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

回答 26

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

def parseIntOrFloat( aString ):
    return eval( aString )

它是这样的…

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

从理论上讲,存在注入漏洞。字符串可以是例如"import os; os.abort()"。但是,由于没有关于字符串来自何处的任何背景,因此可能是理论上的推测。由于问题很模糊,因此尚不清楚此漏洞是否确实存在。

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.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。