Как разобрать строку на float или int в Python?
в Python, как я могу разобрать числовую строку, такую как "545.2222"
к соответствующему значению float,542.2222
? Или разобрать строку "31"
в целое число, 31
?
Я просто хочу знать, как разобрать float string
до float
, и (отдельно) an int string
до int
.
23 ответов
Python метод, чтобы проверить, является ли строка float:
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
вы думаете, что знаете, что такое числа? Ты не так хорош, как думаешь! Неудивительно.
это еще один метод, который заслуживает упоминания здесь,АСТ.literal_eval:
Это можно использовать для безопасной оценки строк, содержащих выражения Python из ненадежных источников без необходимости самостоятельно анализировать значения.
то есть безопасный 'eval'
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
локализация и запятые
вы должны рассмотреть возможность запятых в строковом представлении числа, для таких случаев, как float("545,545.2222")
, который бросает исключение. Вместо этого используйте методы locale
чтобы преобразовать строки в числа и правильно интерпретировать запятые. The locale.atof
метод преобразуется в float за один шаг, как только локаль была установлена для желаемого соглашения о количестве.
Пример 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
тоже имеется, но аргумент должен быть целым числом.
пользователи codelogic и Харлей верны, но имейте в виду, если вы знаете, что строка является целым числом (например, 545), вы можете вызвать int("545") без первого приведения к плаванию.
Если ваши строки находятся в списке, вы также можете использовать функцию map.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
это хорошо, только если они все одного типа.
Если вы не против сторонних модулей, вы можете проверить 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
в Python, как я могу разобрать числовую строку, такую как" 545.2222", на соответствующее значение float, 542.2222? Или разобрать строку " 31 " на целое число, 31? Я просто хочу знать, как разобрать строку float на float и (отдельно) строку int на int.
хорошо, что вы просите сделать это отдельно. Если вы смешиваете их, вы можете настроить себя на проблемы позже. Простой ответ есть:
"545.2222"
плавать:
>>> float("545.2222")
545.2222
"31"
целому числу:
>>> int("31")
31
другие преобразования, ints В и из строк и литералов:
преобразования из различных баз, и вы должны знать базы заранее (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
если вы не знаете базу в заранее, но вы знаете, что у них будет правильный префикс, Python может сделать это для вас, если вы передадите 0
в качестве базового:
>>> 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
делая двусмысленные питон 2 octals совместим с Python 3
если вы видите целое число, которое начинается с 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, которая делает что-то подобное, то есть возвращает integer или float, и если данная строка 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')
'12'
>>> parseStr('12.2.2')
'12.2.2'
на в YAML parser может помочь вам выяснить, какой тип данных ваша строка. Использовать 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'>
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
Я использую эту функцию для этого
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
вам нужно принять во внимание округление, чтобы сделать это правильно.
т. е. 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)
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')
это исправленная версия of 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
Я удивлен, что никто не упомянул регулярное выражение, потому что иногда строка должна быть подготовлена и нормализована перед приведением к номеру
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
Python имеют эту большую гибкость разбора в одном лайнере.
str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
для typecast в python используйте функции конструктора типа, передавая строку (или любое значение, которое вы пытаетесь привести) в качестве параметра.
например:
>>>float("23.333")
23.333
за кулисами python вызывает объекты __float__
метод, который должен возвращать плавающее представление параметра. Это особенно эффективно, так как вы можете определить свои собственные типы (используя классы) с помощью __float__
метод так, что его можно casted в поплавок используя поплавок(мой_объект).
использование:
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()
Это самый Питонический способ, который я мог придумать.
использование:
>>> 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'>
вот еще одна интерпретация вашего вопроса (подсказка: это расплывчато). Возможно, вы ищете что-то вроде этого:
def parseIntOrFloat( aString ):
return eval( aString )
как это работает...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
теоретически, есть уязвимость инъекции. Строка может быть, например,"import os; os.abort()"
. Однако без какого-либо фона о том, откуда берется строка, возможность является теоретической спекуляцией. Поскольку вопрос неясен, совсем не ясно, является ли эта уязвимость существует или нет.