如何将字符串转换为整数或浮点数,优先转换为整数?

13 投票
5 回答
30924 浏览
提问于 2025-04-16 15:25

我在寻找答案的时候没有找到合适的,所以我决定分享我自己的解决方案,希望能帮助到其他人,也希望有人能纠正我如果做错了的话。

我需要做一个自动配置文件解析器,我希望尽可能把数字处理成整数,如果不行再处理成浮点数。一般的尝试/异常转换方法单独使用是行不通的,因为任何浮点数都会被强制转换成整数。

为了更清楚地说明,有人问过这个问题,实际上就是要把数字转换成写配置文件的人想要的样子。所以带小数的数字很可能是想要作为浮点数来处理的。此外,我认为浮点数在某些运算符(比如==、<、>)中可能会有危险,因为浮点数的特性,整数在必要的时候会被转换成浮点数。因此,我更倾向于让数字尽量保持为整数。这不是大问题,只是我个人的一种习惯。

5 个回答

2

eval(s)

eval() 是一个函数,它可以接收一个字符串,并把这个字符串当作Python代码来执行。当你给它一个字符串形式的字面量时,它会返回一个包含该值的Python对象。

不过,从安全的角度来看,这样做并不太好,因为有人可能会输入一些指令,导致你的程序崩溃或者被破坏。你可以在处理之前,要求这个字符串只能包含特定的字符,比如:

eval(s) if not set(s).difference('0123456789.') else None

不过,这样做可能还是不太值得麻烦。话虽如此,你可以让它更复杂一些,允许包含计算的表达式……这可能值得一试!

num = lambda s: eval(s) if not set(s).difference('0123456789. *+-/e') else None

>>> num('10')
10
>>> num('10.0')
10.0
>>> num('1e3')
1000.0
>>> num('4.8 * 10**34')
4.8e+34
>>> num('1+2/3')
1.6666666666666665
3

在这种情况下,事先获得许可可能比事后请求原谅要好,这通常被认为是“Pythonic”的做法,通常会用到 try/except。所以像下面这样简单的代码可能就足够了:

v = float(s) if '.' in s or 'e' in s.lower() else int(s) 

因为有不止一个字符可以表示浮点数,你也可以用以下几种方式来检查这些字符:

import re
pattern = re.compile(r'[.eE]')
v = float(s) if pattern.findall(s) else int(s)

或者

chars = set('.eE')
v = float(s) if any((c in chars) for c in s) else int(s)

最后,如果你想把浮点数的整数部分变成整数,你可以这样做,这和 @John Machin 的 "_dammit_" 函数类似:

v = int(float(s)) if int(float(s)) == float(s) else float(s)
25
def int_or_float(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

如果你想把像 "10.0000" 这样的字符串转换成整数,可以试试这个方法:

def int_dammit_else_float(s):
    f = float(s)
    i = int(f)
    return i if i == f else f

对于像 "1e25" 这样的输入,你想要什么结果呢?

撰写回答