Есть ли Python, эквивалентный параметру endptr для strtod C?
Я пытаюсь написать функцию, которая разбивает строку, содержащую число с плавающей точкой и некоторые единицы. Строка может содержать или не содержать пробелы между числом и единицами.
В С функция strtod
имеет очень удобный параметр, названный endptr
это позволяет вам разобрать начальную часть строки и получить указатель на остаток. Так как это именно то, что мне нужно для этого сценария, мне было интересно, есть ли подобная функциональность, спрятанная где-то в Python.
поскольку float
Сам по себе в настоящее время не предлагает эту функцию, я использую решение регулярных выражений на основе /questions/31585057/kak-izvlech-plavayuschee-chislo-iz-stroki/31585089#31585089:
float_pattern = re.compile(r'[+-]?(?:(?:\d+\.?)|(?:\d*.\d+))(?:[Ee][+-]?\d+)')
def split_units(string):
match = float_pattern.match(string)
if match is None: raise ValueError('not a float')
num = float(match.group())
units = string[match.end():].strip()
return num, units
Это не совсем адекватно по двум причинам. Во-первых, это изобретает колесо. Второе - это то, что он не учитывает локали должным образом без добавления дополнительной сложности (именно поэтому я не хочу заново изобретать колесо).
Для записи хвост строки не может содержать символы, которые будет содержать число. Единственная реальная проблема заключается в том, что я не требую, чтобы единицы отделялись от чисел пробелом, поэтому string.split(maxsplit=1)
не сработает
Есть ли лучший способ получить число с плавающей запятой из начала строки, чтобы я мог обработать остальное как что-то еще?
1 ответ
Я знаю, что это глупое решение, но как насчет этого:
def float_and_more(something):
orig = something
rest = ''
while something:
try:
return float(something), rest
except ValueError:
rest = something[-1] + rest
something = something[:-1]
raise ValueError('Invalid value: {}'.format(orig))
И вы можете использовать это так:
>>> float_and_more('2.5 meters')
(2.5, 'meters')
Если вы хотите использовать это по-настоящему, вы, вероятно, использовали бы io.StringIO
вместо того, чтобы постоянно воссоздавать струны.