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
.
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
int(a)
will give an error that the string isn't a valid integer: ValueError: invalid literal for int() with base 10: '545.222'
, but converting from a float to an int is a supported conversion - David Parks 2018-05-07 17:46
def num(s):
try:
return int(s)
except ValueError:
return float(s)
/
operator on floats/ints. Depending on context it might be preferable to return either int or float, not both - jfs 2012-11-16 14:35
try
to throw an exception when it's not convertible to float - iBug 2018-01-25 12:31
s = u'\u0000'
Matt Hancock 2018-11-12 01:26
ValueError
in the corresponding except
: - marcelm 2019-02-05 22:43
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)
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.
convertibleToFloat
or something similar (current name seems confusing, at least to me) - MKPS 2016-08-28 17:07
float(...)
, so therefore true is convertable to float. False is coerced to 0, which is also a float. This type coercion has nothing to do with C++. Your ancient tomes aren't ancient enough, so discard them and FindOutChristianityNow. He will convert your datatypes in ways that benefit everyone, rather than just the in group clique - Eric Leschinski 2018-09-18 15:14
UTF-8
glyph for a Chinese 4
has been transforming over the years depending on how stackoverflow developers change up their character encoding scheme upon their microsoft toolstack.
It's a curiosity to see it flip flop over the years as new conversion schemes assert their new ideologies. But yes, Any UTF-8
glyph for a Eastern oriental numeric is not a Python float. Bazinga - Eric Leschinski 2018-12-04 18:48
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
```python
import ast ast.literal_eval('1-800-555-1212') -2566
```
To clarify why this is a problem, if you want it to leave phone numbers alone and not assume they are mathematical expressions, then this approach is not for you - royce3 2018-01-16 16:14
float(x) if '.' in x else int(x)
float("nan")
is a perfectly valid float value that the above answer wouldn't catch at al - Ronny Andersson 2017-08-23 14:12
192.168.0.1
; or "This is not a good approach. :)"
Todor Minakov 2019-01-13 19:47
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.
x = '1'; locale.atof(x)
returns 1.0
when I actually want 1
- user5359531 2019-01-02 18:33
locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
user5359531 2019-01-02 18:52
locale.atoi
in a try and using locale.atof
on exception -- it's probably more readable - Mark Chackerian 2019-01-02 19:08
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.
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
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'
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
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
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
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
float("545.2222")
and int(float("545.2222"))
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'>
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
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
except
section if you are doing nothing there? float() would raise for you - Greg0ry 2016-03-19 20:30
int
or float
depending on what the string represents.
It might rise parsing exceptions or [have some unexpected behaviour][1] - Kuzeko 2017-05-18 07:28
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)
int
and float
. And it will give an exception, when n
is a string, as OP desired. Maybe you meant: When an int
result is desired, round
should be done AFTER conversion to float. If the function should ALWAYS return an int, then you don't need the except part -- the entire function body can be int(round(float(input)))
. If the function should return an int if possible, otherwise a float, then javier's original solution is correct - ToolmakerSteve 2013-12-13 06:02
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')
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
Python have this great flexibility of parsing in one liners.
str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
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).
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
You can use str()
to convert any variable to string, int()
to convert string integers to integers and float()
to convert string floating numbers to float value.
str_to_float = float("545.2222")
str_to_int = int("31")
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.
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'>
If you know the str it can be just int or float:
return int(s) if s.isdigit() else float(s)
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.
eval()
is over 3 times as slow as try: int(s) except: float(s)
- Cees Timmerman 2012-10-04 13:12
eval
is bad practice (you must know because you have 310k reputation - U9-Forward 2018-10-01 01:26
type(my_object)
on it. The result can usually be called as a function to do the conversion. For instancetype(100)
results inint
, so you can callint(my_object)
to try convertmy_object
to an integer. This doesn't always work, but is a good "first guess" when coding - robertlayton 2018-07-05 01:18