我有一些Python代码,它运行一个字符串列表,并将它们转换为整数或浮点数(如果可能的话)。对整数执行此操作非常简单
if element.isdigit():
newelement = int(element)
浮点数比较难。现在我正在使用partition('.')来分割字符串,并检查以确保一侧或两侧都是数字。
partition = element.partition('.')
if (partition[0].isdigit() and partition[1] == '.' and partition[2].isdigit())
or (partition[0] == '' and partition[1] == '.' and partition[2].isdigit())
or (partition[0].isdigit() and partition[1] == '.' and partition[2] == ''):
newelement = float(element)
这是可行的,但显然if语句有点麻烦。我考虑的另一个解决方案是将转换封装在一个try/catch块中,看看它是否成功,如这个问题所述。
有人有其他想法吗?对分区和尝试/捕获方法的相对优点有什么看法?
我尝试了上面的一些简单的选项,使用了一个尝试测试转换为浮点数,并发现在大多数回复中有一个问题。
简单测试(按照上面的答案):
entry = ttk.Entry(self, validate='key')
entry['validatecommand'] = (entry.register(_test_num), '%P')
def _test_num(P):
try:
float(P)
return True
except ValueError:
return False
问题出现在:
输入“-”来开始一个负数:
然后尝试float('-'),但失败
你输入一个数字,然后尝试删除所有的数字
然后尝试float("),同样也会失败
我的快速解决方案是:
def _test_num(P):
if P == '' or P == '-': return True
try:
float(P)
return True
except ValueError:
return False
如果你不需要担心科学或其他数字的表达式,并且只处理可以是带句号或不带句号的数字的字符串:
函数
def is_float(s):
result = False
if s.count(".") == 1:
if s.replace(".", "").isdigit():
result = True
return result
Lambda版本
is_float = lambda x: x.replace('.','',1).isdigit() and "." in x
例子
if is_float(some_string):
some_string = float(some_string)
elif some_string.isdigit():
some_string = int(some_string)
else:
print "Does not convert to int or float."
这样你就不会意外地将一个int型转换为浮点型。
为了多样化,这里有另一种方法。
>>> all([i.isnumeric() for i in '1.2'.split('.',1)])
True
>>> all([i.isnumeric() for i in '2'.split('.',1)])
True
>>> all([i.isnumeric() for i in '2.f'.split('.',1)])
False
编辑:我相信它不会支持所有情况下的浮动,虽然特别是当有一个指数。解出来是这样的。只有val是浮点类型时返回True, int类型返回False,但性能可能不如regex。
>>> def isfloat(val):
... return all([ [any([i.isnumeric(), i in ['.','e']]) for i in val], len(val.split('.')) == 2] )
...
>>> isfloat('1')
False
>>> isfloat('1.2')
True
>>> isfloat('1.2e3')
True
>>> isfloat('12e3')
False