2024-03-28 23:19:45 发布
网友
有没有办法在不使用try/except机制的情况下判断字符串是否表示整数(例如,'3','-17',而不是'3.14'或'asfasfas')?
'3'
'-17'
'3.14'
'asfasfas'
is_int('3.14') = False is_int('-7') = True
你知道,我发现(而且我已经反复测试过)无论出于什么原因,try/except都没有那么好的表现。我经常尝试几种方法来做事情,我认为我从来没有找到过一种方法使用try/except来执行测试中最好的方法,事实上,在我看来,这些方法通常已经接近最坏的,如果不是最坏的。不是每一种情况,但在许多情况下。我知道很多人都说这是“Python式”的方式,但这是我和他们分道扬镳的一个方面。对我来说,它既不是很好的表现,也不是很优雅,所以,我倾向于只用于错误捕获和报告。
我要抱怨的是PHP、perl、ruby、C,甚至是畸形的shell都有简单的函数来测试整型hood的字符串,但是在验证这些假设时的尽职调查让我大吃一惊!显然这种缺乏是一种常见病。
以下是布鲁诺邮报的一个快速而肮脏的编辑:
import sys, time, re g_intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$") testvals = [ # integers 0, 1, -1, 1.0, -1.0, '0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0', '06', # non-integers 'abc 123', 1.1, -1.1, '1.1', '-1.1', '+1.1', '1.1.1', '1.1.0', '1.0.1', '1.0.0', '1.0.', '1..0', '1..', '0.0.', '0..0', '0..', 'one', object(), (1,2,3), [1,2,3], {'one':'two'}, # with spaces ' 0 ', ' 0.', ' .0','.01 ' ] def isInt_try(v): try: i = int(v) except: return False return True def isInt_str(v): v = str(v).strip() return v=='0' or (v if v.find('..') > -1 else v.lstrip('-+').rstrip('0').rstrip('.')).isdigit() def isInt_re(v): import re if not hasattr(isInt_re, 'intRegex'): isInt_re.intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$") return isInt_re.intRegex.match(str(v).strip()) is not None def isInt_re2(v): return g_intRegex.match(str(v).strip()) is not None def check_int(s): s = str(s) if s[0] in ('-', '+'): return s[1:].isdigit() return s.isdigit() def timeFunc(func, times): t1 = time.time() for n in range(times): for v in testvals: r = func(v) t2 = time.time() return t2 - t1 def testFuncs(funcs): for func in funcs: sys.stdout.write( "\t%s\t|" % func.__name__) print() for v in testvals: if type(v) == type(''): sys.stdout.write("'%s'" % v) else: sys.stdout.write("%s" % str(v)) for func in funcs: sys.stdout.write( "\t\t%s\t|" % func(v)) sys.stdout.write("\r\n") if __name__ == '__main__': print() print("tests..") testFuncs((isInt_try, isInt_str, isInt_re, isInt_re2, check_int)) print() print("timings..") print("isInt_try: %6.4f" % timeFunc(isInt_try, 10000)) print("isInt_str: %6.4f" % timeFunc(isInt_str, 10000)) print("isInt_re: %6.4f" % timeFunc(isInt_re, 10000)) print("isInt_re2: %6.4f" % timeFunc(isInt_re2, 10000)) print("check_int: %6.4f" % timeFunc(check_int, 10000))
以下是性能比较结果:
timings.. isInt_try: 0.6426 isInt_str: 0.7382 isInt_re: 1.1156 isInt_re2: 0.5344 check_int: 0.3452
C方法可以扫描一次,然后就可以完成了。我认为,C方法扫描字符串一次是正确的做法。
编辑:
我已经更新了上面的代码,使之能够在Python3.5中工作,并且包含了来自当前最有投票权的答案的check_int函数,并且使用了当前最流行的regex,我可以找到它来测试整型hood。这个正则表达式拒绝像“abc 123”这样的字符串。我加了‘abc 123’作为测试值。
在这一点上,我非常感兴趣地注意到,没有一个被测试的函数,包括try方法、流行的check_int函数和最流行的用于测试整数hood的regex,返回所有测试值的正确答案(好吧,这取决于您认为正确答案是什么;请参见下面的测试结果)。
函数的作用是:自动截断浮点数的小数部分,并返回小数之前的整数部分,除非浮点数首先转换为字符串。
check_int()函数为0和1等值返回false(技术上是整数),为06等值返回true。
以下是当前(Python3.5)测试结果:
isInt_try | isInt_str | isInt_re | isInt_re2 | check_int | 0 True | True | True | True | True | 1 True | True | True | True | True | -1 True | True | True | True | True | 1.0 True | True | False | False | False | -1.0 True | True | False | False | False | '0' True | True | True | True | True | '0.' False | True | False | False | False | '0.0' False | True | False | False | False | '1' True | True | True | True | True | '-1' True | True | True | True | True | '+1' True | True | True | True | True | '1.0' False | True | False | False | False | '-1.0' False | True | False | False | False | '+1.0' False | True | False | False | False | '06' True | True | False | False | True | 'abc 123' False | False | False | False | False | 1.1 True | False | False | False | False | -1.1 True | False | False | False | False | '1.1' False | False | False | False | False | '-1.1' False | False | False | False | False | '+1.1' False | False | False | False | False | '1.1.1' False | False | False | False | False | '1.1.0' False | False | False | False | False | '1.0.1' False | False | False | False | False | '1.0.0' False | False | False | False | False | '1.0.' False | False | False | False | False | '1..0' False | False | False | False | False | '1..' False | False | False | False | False | '0.0.' False | False | False | False | False | '0..0' False | False | False | False | False | '0..' False | False | False | False | False | 'one' False | False | False | False | False | <obj..> False | False | False | False | False | (1, 2, 3) False | False | False | False | False | [1, 2, 3] False | False | False | False | False | {'one': 'two'} False | False | False | False | False | ' 0 ' True | True | True | True | False | ' 0.' False | True | False | False | False | ' .0' False | False | False | False | False | '.01 ' False | False | False | False | False |
刚才我试着添加这个函数:
def isInt_float(s): try: return float(str(s)).is_integer() except: return False
它的性能几乎和check_int(0.3486)一样好,对于1.0和0.0以及+1.0和0这样的值,它返回true。0等等。但它也会返回“06”的真值,所以。我想是你选了毒药吧。
如果您真的对到处使用try/except感到厌烦,请编写一个helper函数:
try/except
def RepresentsInt(s): try: int(s) return True except ValueError: return False >>> print RepresentsInt("+123") True >>> print RepresentsInt("10.0") False
这将是更多的代码来精确地覆盖Python认为是整数的所有字符串。我说在这件事上做点恶毒的事。
你知道,我发现(而且我已经反复测试过)无论出于什么原因,try/except都没有那么好的表现。我经常尝试几种方法来做事情,我认为我从来没有找到过一种方法使用try/except来执行测试中最好的方法,事实上,在我看来,这些方法通常已经接近最坏的,如果不是最坏的。不是每一种情况,但在许多情况下。我知道很多人都说这是“Python式”的方式,但这是我和他们分道扬镳的一个方面。对我来说,它既不是很好的表现,也不是很优雅,所以,我倾向于只用于错误捕获和报告。
我要抱怨的是PHP、perl、ruby、C,甚至是畸形的shell都有简单的函数来测试整型hood的字符串,但是在验证这些假设时的尽职调查让我大吃一惊!显然这种缺乏是一种常见病。
以下是布鲁诺邮报的一个快速而肮脏的编辑:
以下是性能比较结果:
C方法可以扫描一次,然后就可以完成了。我认为,C方法扫描字符串一次是正确的做法。
编辑:
我已经更新了上面的代码,使之能够在Python3.5中工作,并且包含了来自当前最有投票权的答案的check_int函数,并且使用了当前最流行的regex,我可以找到它来测试整型hood。这个正则表达式拒绝像“abc 123”这样的字符串。我加了‘abc 123’作为测试值。
在这一点上,我非常感兴趣地注意到,没有一个被测试的函数,包括try方法、流行的check_int函数和最流行的用于测试整数hood的regex,返回所有测试值的正确答案(好吧,这取决于您认为正确答案是什么;请参见下面的测试结果)。
函数的作用是:自动截断浮点数的小数部分,并返回小数之前的整数部分,除非浮点数首先转换为字符串。
check_int()函数为0和1等值返回false(技术上是整数),为06等值返回true。
以下是当前(Python3.5)测试结果:
刚才我试着添加这个函数:
它的性能几乎和check_int(0.3486)一样好,对于1.0和0.0以及+1.0和0这样的值,它返回true。0等等。但它也会返回“06”的真值,所以。我想是你选了毒药吧。
如果您真的对到处使用
try/except
感到厌烦,请编写一个helper函数:这将是更多的代码来精确地覆盖Python认为是整数的所有字符串。我说在这件事上做点恶毒的事。
相关问题 更多 >
编程相关推荐