Как мне разобрать строку с плавающей точкой или int в Python?
В Python, как я могу разобрать числовую строку как "545.2222"
в соответствующее значение с плавающей запятой, 545.2222
? Или разобрать строку "31"
в целое число, 31
?
Я просто хочу знать, как разобрать поплавок str
к float
и (отдельно) int str
для int
,
37 ответов
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
Метод 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
Вы думаете, что знаете, какие цифры? Вы не так хороши, как вы думаете! Не большой сюрприз.
def num(s):
try:
return int(s)
except ValueError:
return float(s)
Это еще один метод, который заслуживает упоминания здесь: ast.literal_eval:
Это может быть использовано для безопасной оценки строк, содержащих выражения Python из ненадежных источников, без необходимости разбора значений самостоятельно.
То есть безопасное "eval"
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
Локализация и запятые
Вы должны рассмотреть возможность запятых в строковом представлении числа, для случаев, таких как 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
также доступен, но аргумент должен быть целым числом.
Если вы не против сторонних модулей, вы можете проверить модуль 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
В Python, как я могу разобрать числовую строку, такую как "545.2222", в соответствующее значение с плавающей точкой, 542.2222? Или разобрать строку "31" в целое число 31? Я просто хочу знать, как разобрать строку с плавающей точкой в число с плавающей точкой, и (отдельно) строку 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
Если вы не знаете базу заранее, но знаете, что у них будет правильный префикс, 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
Делаем неоднозначные восьмеричные Python 2 совместимыми с 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
Пользователи codelogic и harley верны, но имейте в виду, что если вы знаете, что строка является целым числом (например, 545), вы можете вызвать int("545") без первого приведения к плавающему значению.
Если ваши строки находятся в списке, вы также можете использовать функцию map.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Это хорошо, только если они все одного типа.
Вопрос кажется немного старым. Но позвольте мне предложить функцию 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'
Синтаксический анализатор 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'>
Я использую эту функцию для этого
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
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
Вы могли бы использовать
json.loads
:
>>> import json
>>> json.loads('123.456')
123.456
>>> type(_)
<class 'float'>
>>>
Как видите, это становится разновидностью
float
.
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')
Вы должны принять во внимание округление, чтобы сделать это правильно.
Т.е. 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 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'>
Я удивлен, что никто не упомянул регулярное выражение, потому что иногда строка должна быть подготовлена и нормализована перед приведением к числу
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
За кулисами питон вызывает объекты __float__
метод, который должен возвращать плавающее представление параметра. Это особенно эффективно, так как вы можете определить свои собственные типы (используя классы) с помощью __float__
метод, так что он может быть брошен в float с помощью float (myobject).
Обрабатывает шестнадцатеричные, восьмеричные, двоичные, десятичные и числа с плавающей запятой.
Это решение будет обрабатывать все строковые соглашения для чисел (все, о чем я знаю).
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)
Python обладает такой большой гибкостью синтаксического анализа в один лайнер.
str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
Это исправленная версия /questions/25781332/kak-mne-razobrat-stroku-s-plavayuschej-tochkoj-ili-int-v-python/25781345#25781345
Это попытается проанализировать строку и вернуть либо 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
это старый вопрос, на который уже есть много ответов. но если вы имеете дело со смешанными целыми числами и числами с плавающей запятой и хотите согласованный способ работы с вашими смешанными данными, вот мое решение с правильной строкой документации:
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)
выход:
Before:
['34.77', '-13', 'jh', '8990', '76_3234_54']
After:
[34.77, -13, None, 8990, 76323454]
Использование:
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()
Это самый Pythonic способ, которым я мог придумать.
Ты можешь использовать str()
преобразовать любую переменную в строку, int()
преобразовать строковые целые числа в целые числа и float()
преобразовать числа с плавающей запятой в число с плавающей запятой.
str_to_float = float("545.2222")
str_to_int = int("31")
Вы можете просто сделать это с помощью
s = '542.22'
f = float(s) # This converts string data to float data with a decimal point
print(f)
i = int(f) # This converts string data to integer data by just taking the whole number part of it
print(i)
Для получения дополнительной информации о разборе типов данных обратитесь к документации по Python!
Если вы не хотите использовать сторонние модули, наиболее надежным решением может быть следующее:
def string_to_int_or_float(s):
try:
f = float(s) # replace s with str(s) if you are not sure that s is a string
except ValueError:
print("Provided string '" + s + "' is not interpretable as a literal number.")
raise
try:
i = int(str(f).rstrip('0').rstrip('.'))
except:
return f
return i
Это может быть не самое быстрое, но оно правильно обрабатывает литеральные числа там, где многие другие решения терпят неудачу, например:
>>> string_to_int_or_float('789.')
789
>>> string_to_int_or_float('789.0')
789
>>> string_to_int_or_float('12.3e2')
1230
>>> string_to_int_or_float('12.3e-2')
0.123
>>> string_to_int_or_float('4560e-1')
456
>>> string_to_int_or_float('4560e-2')
45.6
Если вы хотите изменить тип на какой-либо другой тип данных, вы можете использовать явное приведение типов, под этим я подразумеваю, что вам нужно использоватьint()
для изменения типа строки наinteger
иfloat()
изменить его наfloat
тип.
Но если мы рассмотрим концепцию приведения типов, мы поймем, что приведение типов не является хорошим выбором для программиста до тех пор, пока оно не будет необходимо, и, следовательно, мы должны использовать приведение типов только в тех случаях, когда это является серьезным требованием, например, когда вы используете входные данные. функция для ввода введенного пользователем значения.
Бонусный совет: вы также можете использовать приведение типов для изменения s наlist
s, а затем конвертируйте их обратно в s, и таким образом вы сможете вносить изменения вtuple
который является неизменяемым типом данных (list()
иtuple()
— соответствующие функции).