Как в Python разобрать числовую строку, например "545.2222", на соответствующее ей значение с плавающей запятой, 545.2222? Или разобрать строку "31" до целого числа, 31?
Я просто хочу знать, как разобрать плаватьstr на float и (отдельно) intstr на int.
int(x) if int(x) == float(x) else float(x)@tcpaiva ValueError: invalid literal for int() with base 10: '1.5'.






float("545.2222") и int(float("545.2222"))
Это даст вам объект с плавающей запятой, если ваша строка окажется равной «0» или «0.0», а не int, которое она дает для других допустимых чисел.
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
просто интересно, почему в конце стоит «04»? почему не просто «00»? также моя текущая версия python не имеет «04».
@MangatRaiModi Числа с плавающей запятой по своей сути несовершены для представления десятичных дробей. Для получения дополнительной информации см. stackoverflow.com/q/21895756/931277.
почему не просто int(a), а int(float(a))?
int(a) выдаст ошибку о том, что строка не является допустимым целым числом: ValueError: invalid literal for int() with base 10: '545.222', но преобразование из числа с плавающей запятой в int является поддерживаемым преобразованием.
Вы должны обращаться с ValueError, если хотите быть в безопасности.
return int(a) if float(a) == int(float(a)) else float(a)@MangatRaiModi python недавно изменил свою политику округления для чисел с плавающей запятой, раньше он использовал фиксированное количество цифр, теперь он использует представление «кратчайшего пути туда и обратно».
Пользователи codelogic и Харлей верны, но имейте в виду, что если вы знаете, что строка является целым числом (например, 545), вы можете вызвать int ("545") без предварительного преобразования в float.
Если ваши строки находятся в списке, вы также можете использовать функцию карты.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Только хорошо, если все они одного типа.
Вот еще одна интерпретация вашего вопроса (подсказка: она расплывчата). Возможно, вы ищете что-то вроде этого:
def parseIntOrFloat( aString ):
return eval( aString )
Это работает так ...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
Теоретически есть инъекционная уязвимость. Строка может быть, например, "import os; os.abort()". Однако без какой-либо информации о том, откуда взялась струна, такая возможность является теоретическим предположением. Поскольку вопрос расплывчатый, совсем не ясно, существует эта уязвимость на самом деле или нет.
Даже если его ввод на 100% безопасен, eval() более чем в 3 раза медленнее, чем try: int(s) except: float(s).
Что ж, eval - плохая практика (вы должны знать, потому что у вас репутация 310k)
def num(s):
try:
return int(s)
except ValueError:
return float(s)
Смешивание скрытый с плавающими / целыми числами может привести к незначительным ошибкам из-за возможной потери точности при работе с плавающими точками или к другим результатам для оператора / с плавающими / целыми числами. В зависимости от контекста может быть предпочтительнее возвращать либо int, либо float, а не то и другое одновременно.
@ J.F.Sebastian: Вы совершенно правы, но бывают случаи, когда вы хотите, чтобы исходные данные диктовали, какой именно. Позволяя вводу диктовать, какой из них может хорошо работать с утиным набором текста.
Вы можете вложить еще один try, чтобы генерировать исключение, когда он не может быть преобразован в плавающий.
Не работает с s = u'\u0000'
@iBug Хорошая идея! Рекомендую закинуть ValueError в соответствующий except: P
float(x) if '.' in x else int(x)
Примечание: будьте осторожны при работе с суммой денег, переданной в виде строк, поскольку в некоторых странах в качестве десятичных разделителей используется ",".
@Emile: Я бы не назвал «2e-3» «крайним случаем». Этот ответ просто неверен.
@BenG НЕ манипулируйте деньгами как плавающими. Это напрашивается на неприятности. Используйте десятичную дробь для денег! (Но ваш комментарий по поводу ',' по-прежнему актуален и важен)
Не забывайте, что «не число» (NaN) и +/- бесконечность также являются допустимыми значениями с плавающей запятой. Итак, float("nan") - это совершенно допустимое значение с плавающей запятой, которое в приведенном выше ответе вообще не улавливается
Легко взламывается по IP-адресу - 192.168.0.1; или "This is not a good approach. :)"
Вы должны принять во внимание округление, чтобы сделать это правильно.
Т.е. интервал (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)
Хорошая точка зрения. Однако это вызывает инфляцию, поэтому Python 3 и другие современные языки используют банковское округление.
Этот ответ неверен (как написано изначально). Он смешивает два случая: int и float. И он выдаст исключение, когда n является строкой, как требуется OP. Возможно, вы имели в виду: Когда желателен результат int, round должен выполняться ПОСЛЕ преобразования в число с плавающей запятой. Если функция должна ВСЕГДА возвращать int, тогда вам не нужна часть except - все тело функции может быть int(round(float(input))). Если функция должна возвращать int, если это возможно, в противном случае - float, то исходное решение Хавьера правильное!
Вопрос кажется немного старым. Но позвольте мне предложить функцию 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'
1e3 - это число в Python, но строка в соответствии с вашим кодом.
Я предпочитаю этот ответ.
Это еще один метод, который заслуживает упоминания здесь, 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.
То есть безопасный eval
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
это нет хорошее решение проблемы. Он отлично работает в Python 2, но в Python 3 происходит следующее: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Чтобы прояснить, почему это проблема, если вы хотите, чтобы телефонные номера оставались в покое и не предполагали, что они являются математическими выражениями, то этот подход не для вас.
@ royce3 Да, это хороший аргумент, и пользователям следует остерегаться. Изначально поведение было изменено для решения некоторых проблем с синтаксическим анализом сложных литералов. Возможно, это ошибка в ast.literal_eval и уже обсуждалась здесь.
Парсер 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'>
Вы должны учитывать возможность использования запятых в строковом представлении числа в таких случаях, как 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 - Европейские соглашения о нумерации
В большинство стран мира для десятичных знаков используются запятые, а не точки. В этом примере с французской локалью запятая правильно обрабатывается как десятичный знак:
>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222
Также доступен метод locale.atoi, но аргумент должен быть целым числом.
Это кажется идеальным решением, когда вы знаете, следует ли возвращать float или int, но как вы можете заставить это возвращать int только в том случае, если int был передан? Например, x = '1'; locale.atof(x) возвращает 1.0, когда мне действительно нужен 1.
Я полагаю, что, используя метод Дино, можно было бы использовать что-то вроде этого: locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
Я бы рекомендовал использовать метод Хавьера, описанный выше (обертывание locale.atoi в попытке и использование locale.atof в исключительных случаях - это, вероятно, более читабельно.
def is_float(value):
try:
float(value)
return True
except:
return False
Более длинное и точное название этой функции могло бы быть: 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
Вы думаете, что знаете, что такое числа? Вы не так хороши, как думаете! Не большой сюрприз.
Таким образом, улавливание широких исключений, уничтожение канареек и поглощение исключения создает крошечный шанс того, что допустимое значение с плавающей запятой в виде строки вернет false. Строка кода float(...) может выйти из строя по любой из тысячи причин, не имеющих ничего общего с содержимым строки. Но если вы пишете жизненно важное программное обеспечение на языке прототипов типа «утка», таком как Python, то у вас возникают гораздо более серьезные проблемы.
Итак, true становится 1, то есть я унаследовал от C++, я думаю
Я опубликовал этот ответ в 2014 году. Этот глиф UTF-8 для китайского 4 трансформировался на протяжении многих лет в зависимости от того, как разработчики stackoverflow меняют свою схему кодировки символов в своем стеке инструментов Microsoft. Любопытно наблюдать, как с годами все меняется, поскольку новые схемы конверсии отстаивают свои новые идеологии. Но да, любой глиф UTF-8 для восточно-восточного числового значения не является поплавком Python. Bazinga.
как это может быть так поддержано, за таким широким исключением?
Все, что между ними есть пробелы, не может быть преобразовано, например "- 12.3" и "45 e6".
Это исключение должно быть ограничено до TypeError, ValueError.
Если вы не против сторонних модулей, вы можете проверить модуль быстрые номера. Он предоставляет функцию под названием 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
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.
Хорошо, что вы просите сделать это отдельно. Если вы их смешиваете, возможно, вы создадите себе проблемы позже. Простой ответ:
"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
Если вы не знаете базу заранее, но знаете, что у них будет правильный префикс, 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
Если вы видите целое число, которое начинается с 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
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, если вы там ничего не делаете? float () поднимет за вас.
вы правы, я полагаю, что я скопировал и вставил из функции, которая вызывала особое исключение. буду редактировать. Благодарность
Это попытается проанализировать строку и вернуть либо int, либо float, в зависимости от того, что представляет собой строка. Это может вызвать исключения при синтаксическом анализе или [иметь непредвиденное поведение] [1].
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')
Использовать:
>>> 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 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()
Это самый питонический способ, который я мог придумать.
Генератор останавливается после первой интерпретации float. Блок try… catch, вероятно, должен находиться внутри цикла for.
Это исправленная версия из 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 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
Обратите внимание, что parse_str(' 1') (с пробелом) вернет None, а не 1.
Я удивлен, что никто не упомянул регулярное выражение, потому что иногда строка должна быть подготовлена и нормализована перед преобразованием в число.
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 используйте функции конструктора типа, передавая строку (или любое другое значение, которое вы пытаетесь преобразовать) в качестве параметра.
Например:
>>>float("23.333")
23.333
За кулисами python вызывает метод __float__ объектов, который должен возвращать представление параметра в виде числа с плавающей запятой. Это особенно эффективно, поскольку вы можете определять свои собственные типы (используя классы) с помощью метода __float__, чтобы его можно было преобразовать в float с помощью float (myobject).
Это функция, которая преобразует любой object (не только str) в int или float, в зависимости от того, предоставлена ли фактическая строка выглядит какint или float. Кроме того, если это объект, который имеет методы __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
Обрабатывает шестнадцатеричное, восьмеричное, двоичное, десятичное и плавающее числа.
Это решение будет обрабатывать все строковые соглашения для чисел (все, о чем я знаю).
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)
Передайте свою строку в эту функцию:
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'>
Используя методы int и float, мы можем преобразовать строку в integer и float.
s = "45.8"
print(float(s))
y='67'
print(int(y))
Этот ответ не добавляет ничего нового. См., Например, этот ответ, который дает ту же информацию и многое другое.
для числа и символа вместе:
string_for_int = "498 results should get"
string_for_float = "498.45645765 results should get"
первый импорт re:
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
a = int(float(a)) if int(float(a)) == float(a) else float(a)
Как правило, если у вас есть объект в Python и вы хотите преобразовать к этого типа объекта, вызовите для него
type(my_object). Результат обычно можно вызвать как функцию для преобразования. Например,type(100)приводит кint, поэтому вы можете вызватьint(my_object), чтобы попытаться преобразоватьmy_objectв целое число. Это не всегда работает, но это хорошая «первая догадка» при кодировании.