如何根据所需的精度将数字解析为int或float?

要求:

>输入可以是字符串或数字
>如果输入可以被视为int而不会丢失精度,则转换为int
>如果输入可以被视为浮点数,则转换为浮点数

这是我使用它的代码部分.

def make_operand(symbol, left=None, right=None):
    valid_symbols = ['*', '/', '+', '-']
    if symbol in valid_symbols:
        return Operand(symbol, left, right)

    as_int = re.compile("^-?[0-9]+$").match(str(symbol))
    as_float = re.compile("^[-+]?[0-9]*\.?[0-9]+$").match(str(symbol))

    as_number = int(symbol) if as_int else float(symbol) if as_float else None

    if as_number:
        return NumericOperand(as_number)

    raise ValueError("Invalid symbol or number")

这有效,但它看起来很乱,闻起来有点不对劲.

使用try块的实现也可以,但似乎不太简单:

    as_number = None
    try:
        as_float = float(symbol)
    except ValueError:
        as_float = None

    if as_float:
        as_int = int(as_float)
        as_number = as_int if as_int == as_float else as_float

    if as_number:
        return NumericOperand(as_number)

    raise ValueError("Invalid symbol or number")

有更好的方法,还是其中一种接近Pythonic的做法?

最佳答案 如果您不介意第三方模块,那么有一个名为
fastnumbers的C-exension模块就是为此目的而设计的.
fast_real功能完全符合您的要求(假设您使用coerce = True,可在fastnumbers上使用> = 0.7.4).

完全披露,我是作者.

>>> from fastnumbers import fast_real
>>> fast_real('56')
56
>>> fast_real('56.0')
56
>>> fast_real('56.07')
56.07
>>> fast_real('56.07 lb')
'56.07 lb'
>>> fast_real(56.07)
56.07
>>> fast_real(56.0)
56.0
>>> fast_real(56.0, coerce=True)
56
>>> fast_real(56)
56
>>> fast_real('56.07 lb', raise_on_invalid=True) 
Traceback (most recent call last):
  ...
ValueError: could not convert string to float: '56.07 lb'
点赞