Python,确定字符串是否应转换为Int或Float

Man*_*rra 14 python decimal-point type-conversion

我想将字符串转换为最可能的数据类型:int或float.

我有两个字符串:

value1="0.80"     #this needs to be a float
value2="1.00"     #this needs to be an integer.
Run Code Online (Sandbox Code Playgroud)

我如何确定value1应该是Float,而value2应该是Python中的Integer?

glg*_*lgl 24

def isfloat(x):
    try:
        a = float(x)
    except ValueError:
        return False
    else:
        return True

def isint(x):
    try:
        a = float(x)
        b = int(a)
    except ValueError:
        return False
    else:
        return a == b
Run Code Online (Sandbox Code Playgroud)

  • 当然,首先应该测试`isint()`,然后只有当前者返回`False`时才测试`isfloat()`. (2认同)
  • 对于非常大的数字来说这是错误的。例如,float("10000000000000000.5") 是 1e+16,int(1e+16) 是 1e+16,但该数字不是 int。 (2认同)

eca*_*mur 16

Python float对象有一个is_integer方法:

from ast import literal_eval
def parses_to_integer(s):
    val = literal_eval(s)
    return isinstance(val, int) or (isinstance(val, float) and val.is_integer())
Run Code Online (Sandbox Code Playgroud)

  • 这会给像“120.0”这样的字符串带来误报。 (2认同)

shr*_*use 7

当我试图确定两个 XML 文档之间的差异时,我必须处理确保“1.0”转换为“1”的情况。所以我写了这个函数来帮助我。我还认为,当相关字符串文字为“True”或“False”时,其他一些解决方案将会失败。无论如何,这个功能对我来说非常有用。我希望它也能帮助你。

from ast import literal_eval

def convertString(s):
    '''
    This function will try to convert a string literal to a number or a bool
    such that '1.0' and '1' will both return 1.

    The point of this is to ensure that '1.0' and '1' return as int(1) and that
    'False' and 'True' are returned as bools not numbers.

    This is useful for generating text that may contain numbers for diff
    purposes.  For example you may want to dump two XML documents to text files
    then do a diff.  In this case you would want <blah value='1.0'/> to match
    <blah value='1'/>.

    The solution for me is to convert the 1.0 to 1 so that diff doesn't see a
    difference.

    If s doesn't evaluate to a literal then s will simply be returned UNLESS the
    literal is a float with no fractional part.  (i.e. 1.0 will become 1)

    If s evaluates to float or a float literal (i.e. '1.1') then a float will be
    returned if and only if the float has no fractional part.

    if s evaluates as a valid literal then the literal will be returned. (e.g.
    '1' will become 1 and 'False' will become False)
    '''


    if isinstance(s, str):
        # It's a string.  Does it represnt a literal?
        #
        try:
            val = literal_eval(s)
        except:
            # s doesn't represnt any sort of literal so no conversion will be
            # done.
            #
            val = s
    else:
        # It's already something other than a string
        #
        val = s

    ##
    # Is the float actually an int? (i.e. is the float 1.0 ?)
    #
    if isinstance(val, float):
        if val.is_integer(): 
            return int(val)

        # It really is a float
        return val

    return val
Run Code Online (Sandbox Code Playgroud)

该函数的单元测试的输出产生:

convertString("1")=1; we expect 1
convertString("1.0")=1; we expect 1
convertString("1.1")=1.1; we expect 1.1
convertString("010")=8; we expect 8
convertString("0xDEADBEEF")=3735928559; we expect 3735928559
convertString("hello")="hello"; we expect "hello"
convertString("false")="false"; we expect "false"
convertString("true")="true"; we expect "true"
convertString("False")=False; we expect False
convertString("True")=True; we expect True
convertString(sri.gui3.xmlSamples.test_convertString.A)=sri.gui3.xmlSamples.test_convertString.A; we expect sri.gui3.xmlSamples.test_convertString.A
convertString(<function B at 0x7fd9e2f27ed8>)=<function B at 0x7fd9e2f27ed8>; we expect <function B at 0x7fd9e2f27ed8>
convertString(1)=1; we expect 1
convertString(1.0)=1; we expect 1
convertString(1.1)=1.1; we expect 1.1
convertString(3735928559)=3735928559; we expect 3735928559
convertString(False)=False; we expect False
convertString(True)=True; we expect True
Run Code Online (Sandbox Code Playgroud)

单元测试代码如下:

import unittest

# just  class for testing that the class gets returned unmolested.
#
class A: pass

# Just a function
#
def B(): pass

class Test(unittest.TestCase):


    def setUp(self):
        self.conversions = [
            # input      | expected
            ('1'         ,1         ),
            ('1.0'       ,1         ), # float with no fractional part
            ('1.1'       ,1.1       ),
            ('010'       ,8         ), # octal
            ('0xDEADBEEF',0xDEADBEEF), # hex
            ('hello'     ,'hello'   ),
            ('false'     ,'false'   ),
            ('true'      ,'true'    ),
            ('False'     ,False     ), # bool
            ('True'      ,True      ), # bool
            (A           ,A         ), # class
            (B           ,B         ), # function
            (1           ,1         ),
            (1.0         ,1         ), # float with no fractional part
            (1.1         ,1.1       ),
            (0xDEADBEEF  ,0xDEADBEEF),
            (False       ,False     ),
            (True        ,True      ),
        ]


    def testName(self):
        for s,expected in self.conversions:
            rval = convertString(s)
            print 'convertString({s})={rval}; we expect {expected}'.format(**locals())
            self.assertEqual(rval, expected)


if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()
Run Code Online (Sandbox Code Playgroud)


ZuL*_*uLu 5

def coerce(x):
    try:
        a = float(x)
        b = int(x)
        if a != b:
            return a
        else:
            return b
    except:
        raise ValueError("failed to coerce str to int or float")
Run Code Online (Sandbox Code Playgroud)

  • 对于浮点数,这将失败。如果 `x == 0.5`,则行 `b = int(x)` 将立即抛出 ValueError 异常,并且永远不会执行 `if a == b` 条件。 (2认同)