Ada*_*tan 413 python string integer
有没有办法判断一个字符串是否代表一个整数(例如'3','-17'但不是'3.14'或'asfasfas')没有使用try/except机制?
is_int('3.14') = False
is_int('-7') = True
Run Code Online (Sandbox Code Playgroud)
Sil*_*ost 671
您可以使用正整数.isdigit:
>>> '16'.isdigit()
True
Run Code Online (Sandbox Code Playgroud)
但它不适用于负整数.假设你可以尝试以下方法:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
Run Code Online (Sandbox Code Playgroud)
它不适用于'16.0'格式,这与int此类意义上的类似.
编辑:
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
Run Code Online (Sandbox Code Playgroud)
Tri*_*ych 355
如果你真的只是厌倦try/except了在各处使用s,请写一个帮助函数:
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
>>> print RepresentsInt("+123")
True
>>> print RepresentsInt("10.0")
False
Run Code Online (Sandbox Code Playgroud)
这将是更多的代码来完全覆盖Python认为整数的所有字符串.我说这只是pythonic.
Sha*_*ais 88
你知道,我已经找到了(而且我已经反复测试过这种情况),无论出于何种原因,尝试/除了不能很好地执行.我经常尝试几种做事方式,我认为我从未找到过使用try/except来执行最佳测试的方法,事实上在我看来这些方法通常都接近于最坏的,如果不是最坏的.并非在所有情况下,但在许多情况下.我知道很多人都说这是"Pythonic"的方式,但这是我与他们分道扬with的一个方面.对我而言,它既不是非常高效也不是非常优雅,因此,我倾向于仅将其用于错误捕获和报告.
我会抱怨PHP,perl,ruby,C,甚至是怪异的shell都有简单的函数来测试整数引擎的字符串,但是在验证这些假设的尽职调查让我感到沮丧!显然这种缺乏是一种常见的疾病.
这是Bruno的帖子快速而又脏的编辑:
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))
Run Code Online (Sandbox Code Playgroud)
以下是性能比较结果:
timings..
isInt_try: 0.6426
isInt_str: 0.7382
isInt_re: 1.1156
isInt_re2: 0.5344
check_int: 0.3452
Run Code Online (Sandbox Code Playgroud)
AC方法可以扫描一次,然后完成.我认为,一次扫描字符串的AC方法将是正确的事情.
编辑:
我已经更新了上面的代码以在Python 3.5中工作,并包含当前最多投票答案中的check_int函数,并使用我可以找到的当前最流行的正则表达式来测试整数引擎.这个正则表达式拒绝像'abc 123'这样的字符串.我添加了'abc 123'作为测试值.
对我来说非常有趣的是,在这一点上,测试的任何功能,包括try方法,流行的check_int函数,以及用于测试整数引擎的最流行的正则表达式,都会返回所有的正确答案.测试值(嗯,取决于您认为正确的答案;请参阅下面的测试结果).
内置的int()函数以静默方式截断浮点数的小数部分,并返回小数之前的整数部分,除非浮点数首先转换为字符串.
对于像0.0和1.0这样的值(技术上是整数),check_int()函数返回false,对于像'06'这样的值,返回true.
以下是当前(Python 3.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 |
Run Code Online (Sandbox Code Playgroud)
刚才我尝试添加这个功能:
def isInt_float(s):
try:
return float(str(s)).is_integer()
except:
return False
Run Code Online (Sandbox Code Playgroud)
它的执行效果几乎和check_int(0.3486)一样,并且对于1.0和0.0以及+1.0和0以及.0之类的值返回true,依此类推.但它也会在'06'中返回true,所以.我想,选择你的毒药.
Gre*_*ill 25
使用正则表达式:
import re
def RepresentsInt(s):
return re.match(r"[-+]?\d+$", s) is not None
Run Code Online (Sandbox Code Playgroud)
如果您还必须接受小数分数:
def RepresentsInt(s):
return re.match(r"[-+]?\d+(\.0*)?$", s) is not None
Run Code Online (Sandbox Code Playgroud)
如果您经常这样做,为了提高性能,请仅使用一次编译正则表达式re.compile().
Cat*_*lts 23
str.isdigit() 应该可以。
例子:
str.isdigit("23") ## True
str.isdigit("abc") ## False
str.isdigit("23.4") ## False
编辑:正如@BuzzMoschetti指出的那样,这种方式将无法获得减号(例如“ -23”)。如果您的input_num可以小于0,请在应用str.isdigit()之前使用re.sub(regex_search,regex_replace,contents )。例如:
import re
input_num="-23"
input_num = re.sub("^-", "", input_num) # "^" indicates to remove the first "-" only.
str.isdigit(input_num) ## True
Bru*_*sky 17
适当的RegEx解决方案将结合Greg Hewgill和Nowell的想法,但不使用全局变量.您可以通过将属性附加到方法来完成此操作.另外,我知道将导入放入方法中是不赞成的,但我想要的是像http://peak.telecommunity.com/DevCenter/Importing#lazy-imports这样的"懒惰模块"效果.
编辑:到目前为止,我最喜欢的技术是使用String对象的专有方法.
#!/usr/bin/env python
# Uses exclusively methods of the String object
def isInteger(i):
i = str(i)
return i=='0' or (i if i.find('..') > -1 else i.lstrip('-+').rstrip('0').rstrip('.')).isdigit()
# Uses re module for regex
def isIntegre(i):
import re
if not hasattr(isIntegre, '_re'):
print("I compile only once. Remove this line when you are confident in that.")
isIntegre._re = re.compile(r"[-+]?\d+(\.0*)?$")
return isIntegre._re.match(str(i)) is not None
# When executed directly run Unit Tests
if __name__ == '__main__':
for obj in [
# integers
0, 1, -1, 1.0, -1.0,
'0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0',
# non-integers
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'}
]:
# Notice the integre uses 're' (intended to be humorous)
integer = ('an integer' if isInteger(obj) else 'NOT an integer')
integre = ('an integre' if isIntegre(obj) else 'NOT an integre')
# Make strings look like strings in the output
if isinstance(obj, str):
obj = ("'%s'" % (obj,))
print("%30s is %14s is %14s" % (obj, integer, integre))
Run Code Online (Sandbox Code Playgroud)
对于不太冒险的班级成员,这是输出:
I compile only once. Remove this line when you are confident in that.
0 is an integer is an integre
1 is an integer is an integre
-1 is an integer is an integre
1.0 is an integer is an integre
-1.0 is an integer is an integre
'0' is an integer is an integre
'0.' is an integer is an integre
'0.0' is an integer is an integre
'1' is an integer is an integre
'-1' is an integer is an integre
'+1' is an integer is an integre
'1.0' is an integer is an integre
'-1.0' is an integer is an integre
'+1.0' is an integer is an integre
1.1 is NOT an integer is NOT an integre
-1.1 is NOT an integer is NOT an integre
'1.1' is NOT an integer is NOT an integre
'-1.1' is NOT an integer is NOT an integre
'+1.1' is NOT an integer is NOT an integre
'1.1.1' is NOT an integer is NOT an integre
'1.1.0' is NOT an integer is NOT an integre
'1.0.1' is NOT an integer is NOT an integre
'1.0.0' is NOT an integer is NOT an integre
'1.0.' is NOT an integer is NOT an integre
'1..0' is NOT an integer is NOT an integre
'1..' is NOT an integer is NOT an integre
'0.0.' is NOT an integer is NOT an integre
'0..0' is NOT an integer is NOT an integre
'0..' is NOT an integer is NOT an integre
'one' is NOT an integer is NOT an integre
<object object at 0x103b7d0a0> is NOT an integer is NOT an integre
(1, 2, 3) is NOT an integer is NOT an integre
[1, 2, 3] is NOT an integer is NOT an integre
{'one': 'two'} is NOT an integer is NOT an integre
Run Code Online (Sandbox Code Playgroud)
alk*_*333 14
>>> "+7".lstrip("-+").isdigit()
True
>>> "-7".lstrip("-+").isdigit()
True
>>> "7".lstrip("-+").isdigit()
True
>>> "13.4".lstrip("-+").isdigit()
False
Run Code Online (Sandbox Code Playgroud)
所以你的功能是:
def is_int(val):
return val.lstrip("-+").isdigit()
Run Code Online (Sandbox Code Playgroud)
我一直这样做 b/c 我对使用 try/except 模式有一种温和但不可否认的非理性厌恶。我用这个:
all([xi in '1234567890' for xi in x])
Run Code Online (Sandbox Code Playgroud)
它不容纳负数,因此您可以去掉左侧的所有减号,然后检查结果是否包含 0-9 的数字:
all([xi in '1234567890' for xi in x.lstrip('-')])
Run Code Online (Sandbox Code Playgroud)
如果您不确定输入是字符串,也可以将 x 传递给 str() :
all([xi in '1234567890' for xi in str(x).lstrip('-')])
Run Code Online (Sandbox Code Playgroud)
在某些(边缘?)情况下,这会崩溃:
type(1E2)给出<class 'float'>而type(10^2)给出<class 'int'>。type(---1)返回<class int>. 但是,它与int('---1')给出错误的解释器并不完全一致,但我的解决方案True以相同的输入返回。因此,它不适用于所有可能的输入,但如果您可以排除这些输入,则可以进行单行检查,False如果 x 不是整数并且Truex 是整数,则返回。但是如果你真的想要完全模拟int()内置行为的行为,你最好使用 try/except。
不知道是不是pythonic,不过是一行,代码的作用比较清楚。
*我的意思不是说解释器忽略前导减号,只是任何数量的前导减号都不会改变结果是整数。int(--1)实际上解释为-(-1), 或 1.int(---1)解释为-(-(-1)), 或 -1。所以偶数个前导减号给出一个正整数,奇数个负号给出一个负整数,但结果总是一个整数。
最简单的方法,我用的
def is_int(item: str) -> bool:
return item.lstrip('-+').isdigit()
Run Code Online (Sandbox Code Playgroud)
Greg Hewgill 的方法缺少一些组件:前导“^”只匹配字符串的开头,并预先编译 re。但是这种方法可以让你避免 try: exept:
import re
INT_RE = re.compile(r"^[-]?\d+$")
def RepresentsInt(s):
return INT_RE.match(str(s)) is not None
Run Code Online (Sandbox Code Playgroud)
我会感兴趣你为什么试图避免尝试:除了?
我认为
s.startswith('-') and s[1:].isdigit()
Run Code Online (Sandbox Code Playgroud)
最好重写为:
s.replace('-', '').isdigit()
Run Code Online (Sandbox Code Playgroud)
因为 s[1:] 也创建了一个新字符串
但更好的解决方案是
s.lstrip('+-').isdigit()
Run Code Online (Sandbox Code Playgroud)
可以用下面的方法来检查。
def check_if_string_is_int(string1):
for character in string1:
if not character.isdigit():
return "Not a number"
else:
return "Is a number"
Run Code Online (Sandbox Code Playgroud)