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

13

当我需要这个答案时,我找不到其他的答案,所以我想为其他人发帖提供我的解决方案,并获得纠正,如果我做错了什么。

我必须制作一个自动配置文件解析器,我更喜欢将数字转换为int或float。通常的try/except转换本身不起作用,因为任何float都会被强制转换为int。

澄清一下,有人问,这种情况基本上是将数字转换为编写配置文件数据的人想要的方式。因此,任何带小数点的东西可能都意味着是float。另外,我认为浮点数对于某些操作符(例如==,<,>)可能是危险的,由于浮点数的性质,而int将在必要时转换为float。因此,我更喜欢数字尽可能地保持在int中。这不是什么大事,只是我自己的一种约定。


1
可能是重复的问题:Python - 将字符串解析为浮点数或整数 - johnsyweb
不是重复;那个问题要求不同的东西。 - John Machin
1
请编辑您的问题,给出明确的示例,以说明“如果可能,将数字转换为int”的含义。特别是,您是否希望将用户意图明显为浮点数的“10.0000”转换为intfloat - John Machin
1
为什么你想要一个“如果可能的int”,如果浮点数也是有效的呢? - detly
5个回答

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",你想得到什么结果?


当我意识到你的第一个解决方案正好符合我的要求时,我感到很傻。我一直在错误地认为int('1.1')会强制转换为1,因为int(1.1)是这样的。感谢你的答案并帮助我纠正了我的错误假设。 - KobeJohn

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)

只有当你知道应该问什么时,才尝试使用“1E-6”。 - John Machin
@John Machin:总的来说是个好观点,但在这里可能仍然可以控制(请参见我的更新)。 - martineau
感谢您的代码Martineau。它非常适合我的需求,并简化了我原本的代码。实际上,我将省略E符号,因为一旦开始处理情况,我认为最好只使用正则表达式来捕获所有情况。 - KobeJohn
@yakiimo:是的,我想可能情况就是这样,正如阿尔伯特·爱因斯坦所说:“把事情尽可能简单化,但不要过于简单”和“任何傻瓜都可以把事情变得更大、更复杂、更暴力。相反,需要一些天才和很多勇气来朝相反的方向前进。”还有“做可能最简单的事情”(他没有说这句话)。 - martineau
@yakiimo,不用谢!当你收到足够的答案并尝试过后,如果其中一个有帮助到你,请务必接受它(通过点击答案旁边的勾形图标)——这是基本的SO礼仪!-) - martineau

2
def int_float_none(x):
    # it may be already int or float 
    if isinstance(x, (int, float)):
        return x
    # all int like strings can be converted to float so int tries first 
    try:
        return int(x)
    except (TypeError, ValueError):
        pass
    try:
        return float(x)
    except (TypeError, ValueError):
        return None

任何传递的对象,上述函数将返回整数或浮点数转换或None。

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

0

尝试检测浮点数并不容易,但检测可能的整数则更容易。

我会尝试检查字符串是否仅包含数字(忽略可能的前导空格或符号),并相应地转换为浮点数或整数:

lst = ['1' , '2.2' , ' -3','+5']

result = [int(x) if x.lstrip(" -+").isdigit() else float(x) for x in lst]

print(result)

输出:

[1, 2.2, -3, 5]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接