Есть ли 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 вместо того, чтобы постоянно воссоздавать струны.

Другие вопросы по тегам