【问题标题】:How can I convert a string to either int or float with priority on int?如何将字符串转换为 int 或具有 int 优先级的浮点数?
【发布时间】:2011-04-09 23:45:31
【问题描述】:

当我想要这个时找不到另一个答案,所以我想我会为其他人发布我自己的解决方案,如果我做错了什么也可以得到更正。

我必须制作一个自动配置文件解析器,如果可能的话,我更喜欢将数字设为 int,如果没有,我更喜欢浮动。通常的 try/except 转换本身不起作用,因为任何浮点数都会被强制转换为 int。

为了澄清有人问,这个案例基本上是将数字转换为编写配置文件数据的人的意图。所以任何带有小数的东西都可能是一个浮点数。此外,由于浮点数的性质,我认为浮点数对于某些运算符(例如 ==、)可能是危险的,并且 int 将在必要时转换为浮点数。因此,如果可能,我更喜欢将数字留在 int 中。没什么大不了的,只是作为我自己的一种约定。

【问题讨论】:

  • 不是重复的;这个问题要求不同的东西。
  • 编辑您的问题以举例说明“尽可能将数字设为 int”的含义。特别是,您是否希望将“10.0000”(用户的意图显然是浮动的)转换为intfloat
  • 如果浮点数仍然有效,为什么还要“int if possible”?

标签: python


【解决方案1】:
def int_or_float(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

如果您想将 "10.0000" 之类的内容转换为 int,请尝试以下操作:

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

"1e25" 这样的输入你想要什么结果?

【讨论】:

  • 哇,当我意识到您的第一个解决方案完全符合我的要求时,我感到很傻。我在错误的理解下工作,因为 int(1.1) 会强制转换为 1。感谢您的回答并帮助我纠正我的错误假设。
【解决方案2】:

在这种情况下,首先获得许可可能比稍后请求宽恕更好,这通常被认为是“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:总体来说不错,但这里可能仍然可以管理(请参阅我的更新)。
  • 感谢代码 martineau。它可以很好地满足我的需求并简化我所拥有的。我实际上会省略 E 表示法,因为一旦您开始处理案例,我认为使用正则表达式来捕获所有案例会更好。
  • @yakiimo:是的,我认为可能是这样,正如阿尔伯特爱因斯坦所说,“让一切尽可能简单,但不要更简单”和“任何傻瓜都可以让事情变得更大,更复杂, “还有“做可能可行的最简单的事情”(他没有说)。
  • @yakiimo,不客气!当您收到足够多的答案并尝试过时,如果有人帮助了您,请务必接受(通过单击答案旁边的复选标记图标)——这是基本的 SO 礼仪!-)
【解决方案3】:

评估

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

【讨论】:

    【解决方案4】:
    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
    

    上面的函数对于任何传递的对象都将返回 int 或 float 转换或 None。

    【讨论】:

      【解决方案5】:

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

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

      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]
      

      【讨论】:

        猜你喜欢
        • 2020-05-23
        • 2021-09-10
        • 1970-01-01
        • 2012-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-16
        • 2013-03-02
        相关资源
        最近更新 更多