有没有一种方法可以判断一个字符串是否表示一个整数(例如'3'
,'-17'
但不是'3.14'
或'asfasfas'
),而不使用try / except机制?
is_int('3.14') == False
is_int('-7') == True
有没有一种方法可以判断一个字符串是否表示一个整数(例如'3'
,'-17'
但不是'3.14'
或'asfasfas'
),而不使用try / except机制?
is_int('3.14') == False
is_int('-7') == True
如果使用正整数,可以使用.isdigit
方法:
>>> '16'.isdigit()
True
不过它不能处理负整数。假设你可以尝试以下方法:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
使用格式为'16.0'
的数据不起作用,这类似于int
类型的强制转换。
编辑:
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
u.isdecimal()
代替 str.isdigit()
。在 Python 2 中,str.isdigit()
的结果会受地区设置的影响。需要注意的是,虽然 u'²'.isdigit()
返回 True,但 int(u'²')
会引发 ValueError 错误。 - jfscheck_int('')
会引发异常,而不是返回 False
。 - wordbug如果您只是厌烦在各个地方使用try/except
,请编写一个辅助函数:
def represents_int(s):
try:
int(s)
except ValueError:
return False
else:
return True
>>> print(represents_int("+123"))
True
>>> print(represents_int("10.0"))
False
要完全覆盖Python认为是整数的所有字符串,需要编写更多的代码。我建议在这个问题上遵循Python语言的风格。
>>> print RepresentsInt(10.0)
返回 True
,否则返回 False
除非: >>> print RepresentsInt(10.06)
返回 True
,否则返回 False
- Dannidtry/except
被使用(即使是包装在函数中)。 - CristiFatiimport 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
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.和.0等值返回true。但是它也会对'06'返回true,所以你可以自行选择。
try
更有效率:isInt_try: 0.6552 / isInt_str: 0.6396 / isInt_re: 1.0296 / isInt_re2: 0.5168。 - Davestr.isdigit()
能够解决问题。
例如:
str.isdigit("23") ## True
str.isdigit("abc") ## False
str.isdigit("23.4") ## False
编辑: 正如@BuzzMoschetti指出的那样,这种方法对于负数(例如“-23”)将会失败。如果您的可能小于0,请在应用之前使用。例如:
import re
input_num = "-23"
input_num = re.sub("^-", "", input_num) ## "^" indicates to remove the first "-" only
str.isdigit(input_num) ## True
s.isnumeric()
和s.isdigit()
有什么区别? - Charlie Parker使用正则表达式:
import re
def RepresentsInt(s):
return re.match(r"[-+]?\d+$", s) is not None
如果您必须接受小数分数:def RepresentsInt(s):
return re.match(r"[-+]?\d+(\.0*)?$", s) is not None
如果你要经常执行这个操作,为了提高性能,请使用re.compile()
只编译一次正则表达式。
#!/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))
对于那些不太冒险的班级成员,这是输出结果:
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
>>> "+7".lstrip("-+").isdigit()
True
>>> "-7".lstrip("-+").isdigit()
True
>>> "7".lstrip("-+").isdigit()
True
>>> "13.4".lstrip("-+").isdigit()
False
那么你的函数将是:
def is_int(val):
return val.lstrip("-+").isdigit()
def is_int(val):
... return val.lstrip("-+").isdigit()
...
is_int("2")
True
这不会导致错误。在我看来,这是最好的答案,实际上符合需求,而不依赖于昂贵或奇怪的解决方案。 - Justus Wingert我经常这样做,因为我有一种轻微但公开的不合理的厌恶情绪,不愿使用try/except模式。我使用以下方式:
all([xi in '1234567890' for xi in x])
all([xi in '1234567890' for xi in x.lstrip('-')])
如果您不确定输入是否为字符串,您也可以将 x 传递给 str():
all([xi in '1234567890' for xi in str(x).lstrip('-')])
这种方法在某些情况下可能会失效:
type(1E2)
返回 <class 'float'>
,而 type(10^2)
返回 <class 'int'>
。type(---1)
返回 <class int>
。然而,它与解释器并不完全一致,因为int('---1')
会报错,但我的解决方案使用相同的输入返回True
。因此,它不能处理所有可能的输入,但如果您可以排除这些输入,它是一个可以在一行代码中运行的检查,如果x不是整数,则返回False
,如果x是整数则返回True
。但是,如果您真的想要完全模拟内置的int()
函数行为,最好使用try/except。
我不知道它是否符合Pythonic标准,但它只有一行代码,而且代码的含义相对清晰。
*我并不是说解释器忽略前导减号,而是说任何数量的前导减号都不会改变结果是整数的事实。例如,int(--1)
实际上被解释为-(-1)
,即1。int(---1)
被解释为-(-(-1))
,即-1。因此,偶数个前导减号得到一个正整数,奇数个减号得到一个负整数,但结果始终是整数。
'12-34'
,这将返回 True
。 - AMC.replace()
和 .lstrip()
的实现都适用于 OP 的示例。 - mRottendef is_int(item: str) -> bool:
return item.lstrip('-+').isdigit()
-+123
got True - yurenchen可以使用以下方法进行检查。
def check_if_string_is_int(string1):
for character in string1:
if not character.isdigit():
return "Not a number"
else:
return "Is a number"
else:
语句。只需要在当前else
所在的位置直接写入 return "是数字"
即可。 - Ronald Souza44
返回 True,但 44
返回 False)。在开头添加 string1 = string1.strip()
可以解决这个问题。 - Ronald Souza