【问题标题】:Interpreting Strings as Other Data Types in Python在 Python 中将字符串解释为其他数据类型
【发布时间】:2012-02-22 18:38:48
【问题描述】:

我正在将一个结构如下的文件读入 python 2.4:

field1: 7
field2: "Hello, world!"
field3: 6.2

这个想法是将它解析成一个字典,该字典以fieldfoo 作为键,冒号后面的任何内容作为值。

我想将冒号后面的任何内容转换为它的“实际”数据类型,也就是说,'7' 应该转换为int"Hello, world!" 转换为字符串等。唯一需要的数据类型要解析的是整数、浮点数和字符串。 python 标准库中是否有一个函数可以让人们轻松地进行这种转换?

唯一应该用来解析的东西是我写的,所以(至少在这种情况下)安全不是问题。

【问题讨论】:

    标签: python string parsing python-2.4


    【解决方案1】:

    strconvlib。

    In [22]: import strconv
    /home/tworec/.local/lib/python2.7/site-packages/strconv.py:200: UserWarning: python-dateutil is not installed. As of version 0.5, this will be a hard dependency of strconv fordatetime parsing. Without it, only a limited set of datetime formats are supported without timezones.
      warnings.warn('python-dateutil is not installed. As of version 0.5, '
    
    In [23]: strconv.convert('1.2')
    Out[23]: 1.2
    
    In [24]: type(strconv.convert('1.2'))
    Out[24]: float
    
    In [25]: type(strconv.convert('12'))
    Out[25]: int
    
    In [26]: type(strconv.convert('true'))
    Out[26]: bool
    
    In [27]: type(strconv.convert('tRue'))
    Out[27]: bool
    
    In [28]: type(strconv.convert('12 Jan'))
    Out[28]: str
    
    In [29]: type(strconv.convert('12 Jan 2018'))
    Out[29]: str
    
    In [30]: type(strconv.convert('2018-01-01'))
    Out[30]: datetime.date
    

    【讨论】:

    【解决方案2】:

    感谢 wim 帮助我弄清楚我需要搜索什么来解决这个问题。

    可以使用eval():

    >>> a=eval("7")
    >>> b=eval("3")
    >>> a+b
    10
    >>> b=eval("7.2")
    >>> a=eval("3.5")
    >>> a+b
    10.699999999999999
    >>> a=eval('"Hello, "')
    >>> b=eval('"world!"')
    >>> a+b
    'Hello, world!'
    

    【讨论】:

    • 太棒了!现在确保不要在源中导入 os,以避免评估像 os.system("rm *") 这样的值。这不是唯一的方法。所以这个方法可行,但不推荐。
    • 这是邪恶且不安全的,但整个脚本是一个快速而肮脏的修复程序,应该(理想情况下)在几个月内丢弃。
    • 我有一个 Q&D awk 脚本,它是我在 1989 年编写的,它实现了一个非常粗糙的商业订单处理器,“直到我们等待的应用程序准备就绪”,据我所知,它直到 1996 年仍在使用,还有一个Q&D 1995 QBasic 军队服务杂务分配器(不管你怎么理解 :) 仍然在 2007 年使用(尽管被其他人修改到无止境,我想),所以我确信“快速&肮脏”程序同样快速但更多比人们通常认为的更脏。
    【解决方案3】:

    对于较旧的 python 版本,就像被问到的那样,可以使用eval 函数,但是为了减少邪恶,dict 作为全局命名空间应该用作第二个参数避免函数调用。

    >>> [eval(i, {"__builtins__":None}) for i in ['6.2', '"Hello, world!"', '7']]
    [6.2, 'Hello, world!', 7]
    

    【讨论】:

      【解决方案4】:

      由于“只有intfloatstr 是需要解析的数据类型”,也许这样的东西对你有用:

      entries = {'field1': '7', 'field2': "Hello, world!", 'field3': '6.2'}
      
      for k,v in entries.items():
          if v.isdecimal():
              conv = int(v)
          else:
              try:
                  conv = float(v)
              except ValueError:
                  conv = v
          entries[k] = conv
      
      print(entries)
      # {'field2': 'Hello, world!', 'field3': 6.2, 'field1': 7}
      

      【讨论】:

        【解决方案5】:

        您可以先尝试使用内置函数int() 将其转换为int。如果字符串不能解释为 int,则会引发 ValueError 异常。然后,您可以尝试使用float() 转换为float。如果这也失败了,那么只返回初始字符串

        def interpret(val):
            try:
                return int(val)
            except ValueError:
                try:
                    return float(val)
                except ValueError:
                    return val
        

        【讨论】:

          【解决方案6】:

          首先将您的输入解析为一对列表,例如fieldN: some_string。您可以使用re 模块轻松完成此操作,或者更简单地使用索引line.strip().find(': ') 的左右切片。然后对值 some_string 使用文字 eval:

          >>> import ast
          >>> ast.literal_eval('6.2')
          6.2
          >>> type(_)
          <type 'float'>
          >>> ast.literal_eval('"Hello, world!"')
          'Hello, world!'
          >>> type(_)
          <type 'str'>
          >>> ast.literal_eval('7')
          7
          >>> type(_)
          <type 'int'>
          

          【讨论】:

          • 我使用的python版本没有ast模块。
          • @MikeSamuel 显然必须首先将输入预处理为 fieldn: string 对,但这部分是微不足道的。 @julio.alegria _ 是交互式解释器中最后返回值的便捷快捷方式。 @Dan ..erm .. 现在你告诉我 ;) 升级 python?你有理由需要使用这么旧的版本吗?
          • @Mike Samuel:安全对我来说不是问题。我不需要解析任何我自己没有用另一个程序编写的东西。不过,请为您指出的评论 +1。
          • @wim,明白了。感谢您的解释。
          • mail.python.org/pipermail/python-list/2009-September/… 这里有人将literal_eval 向后移植到2.4,但这对我来说听起来有点老套。我个人更愿意升级 python 而不是使用它。
          【解决方案7】:

          希望这有助于做你想做的事:

          #!/usr/bin/python
          
          a = {'field1': 7}
          b = {'field2': "Hello, world!"}
          c = {'field3': 6.2}
          
          temp1 = type(a['field1'])
          temp2 = type(b['field2'])
          temp3 = type(c['field3'])
          
          print temp1
          print temp2
          print temp3
          

          【讨论】:

          • 我不想在字典中获取对象的类型,我想将字典中被注释为python类型的字符串转换为它们所代表的类型。
          • 你能发布示例输入和输出,这样更容易理解吗?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-07
          • 2017-11-05
          • 2018-07-17
          • 2023-03-26
          • 1970-01-01
          相关资源
          最近更新 更多