有没有一种方法可以判断一个字符串是否表示一个整数(例如'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
Greg Hewgill的方法缺少了一些组件:在正则表达式中添加一个"^"只匹配字符串的开头,以及预先编译正则表达式。但这种方法可以避免使用try: except:语句。
import re
INT_RE = re.compile(r"^[-]?\d+$")
def RepresentsInt(s):
return INT_RE.match(str(s)) is not None
我很想知道你为什么要避免使用try: except语句?
re.match
在开头隐含了一个 ^
。(这不是很“明确”吗?) 我不记得了,但我肯定在过去遇到过这个问题。因此,我很高兴有这次交流。 - Bruno Bronosky我认为
s.startswith('-') and s[1:].isdigit()
最好重写为:
s.replace('-', '').isdigit()
因为 s[1:] 也会创建一个新的字符串
但更好的解决方案是
s.lstrip('+-').isdigit()
replace
是做什么的吗?另外,这会错误地接受 5-2
这样的输入。 - Ry-s='-'
,将会抛出一个IndexError。 - Anti Earths.lstrip('+-').isdigit()
accepts stuff like -+1
or +++++++1
- user9645前提条件:
int()
行为对我们来说是标准的(有时它很奇怪:“-00”是它的正确输入)。简短回答:
使用以下代码。它是简单的,正确的(而这个线程中的许多变体并不是)并且几乎比try/except
和regex
变体快两倍。
def is_int_str(string):
return (
string.startswith(('-', '+')) and string[1:].isdigit()
) or string.isdigit()
简短回答:
我测试了三种主要的变体:(1) try/except,(2) re.match()和(3)字符串操作(见上文)。第三个变体比try/except
和re.match()
都快大约两倍。顺便说一下:正则表达式变体是最慢的!请参见下面的测试脚本。
import re
import time
def test(func, test_suite):
for test_case in test_suite:
actual_result = func(*test_case[0])
expected_result = test_case[1]
assert (
actual_result == expected_result
), f'Expected: {expected_result} but actual: {actual_result}'
def perf(func, test_suite):
start = time.time()
for _ in range(0, 1_000_000):
test(func, test_suite)
return time.time() - start
def is_int_str_1(string):
try:
int(string)
return True
except ValueError:
return False
def is_int_str_2(string):
return re.match(r'^[\-+]?\d+$', string) is not None
def is_int_str_3(string):
return (
string.startswith(('-', '+')) and string[1:].isdigit()
) or string.isdigit()
# Behavior of built-in int() function is a standard for the following tests
test_suite = [
[['1'], True], # func('1') -> True
[['-1'], True],
[['+1'], True],
[['--1'], False],
[['++1'], False],
[['001'], True], # because int() can read it
[['-00'], True], # because of quite strange behavior of int()
[['-'], False],
[['abracadabra'], False],
[['57938759283475928347592347598357098458405834957984755200000000'], True],
]
time_span_1 = perf(is_int_str_1, test_suite)
time_span_2 = perf(is_int_str_2, test_suite)
time_span_3 = perf(is_int_str_3, test_suite)
print(f'{is_int_str_1.__name__}: {time_span_1} seconds')
print(f'{is_int_str_2.__name__}: {time_span_2} seconds')
print(f'{is_int_str_3.__name__}: {time_span_3} seconds')
is_int_str_1: 4.314162969589233 seconds
is_int_str_2: 5.7216269969940186 seconds
is_int_str_3: 2.5828163623809814 seconds
9.66 | 7.03 | 4.86
,在Python 3.8上:7.78 | 5.56 | 4.57
。 - pepoluan我非常喜欢Shavais的帖子,但我添加了一个测试用例(和内置的isdigit()函数):
def isInt_loop(v):
v = str(v).strip()
# swapping '0123456789' for '9876543210' makes nominal difference (might have because '1' is toward the beginning of the string)
numbers = '0123456789'
for i in v:
if i not in numbers:
return False
return True
def isInt_Digit(v):
v = str(v).strip()
return v.isdigit()
timings..
isInt_try: 0.4628
isInt_str: 0.3556
isInt_re: 0.4889
isInt_re2: 0.2726
isInt_loop: 0.1842
isInt_Digit: 0.1577
使用普通的Python 2.7:
$ python --version
Python 2.7.10
None
(默认情况下在CPython上处理多达2000个“- / +”符号!):#!/usr/bin/env python
def get_int(number):
splits = number.split('.')
if len(splits) > 2:
# too many splits
return None
if len(splits) == 2 and splits[1]:
# handle decimal part recursively :-)
if get_int(splits[1]) != 0:
return None
int_part = splits[0].lstrip("+")
if int_part.startswith('-'):
# handle minus sign recursively :-)
return get_int(int_part[1:]) * -1
# successful 'and' returns last truth-y value (cast is always valid)
return int_part.isdigit() and int(int_part)
一些测试:
tests = ["0", "0.0", "0.1", "1", "1.1", "1.0", "-1", "-1.1", "-1.0", "-0", "--0", "---3", '.3', '--3.', "+13", "+-1.00", "--+123", "-0.000"]
for t in tests:
print "get_int(%s) = %s" % (t, get_int(str(t)))
结果:
get_int(0) = 0
get_int(0.0) = 0
get_int(0.1) = None
get_int(1) = 1
get_int(1.1) = None
get_int(1.0) = 1
get_int(-1) = -1
get_int(-1.1) = None
get_int(-1.0) = -1
get_int(-0) = 0
get_int(--0) = 0
get_int(---3) = -3
get_int(.3) = None
get_int(--3.) = 3
get_int(+13) = 13
get_int(+-1.00) = -1
get_int(--+123) = 123
get_int(-0.000) = 0
您可以使用以下内容来满足您的需求:
def int_predicate(number):
return get_int(number) is not None
在我看来,这可能是最直接和Pythonic的方法。我没有看到这个解决方案,它基本上与正则表达式相同,但没有使用正则表达式。
def is_int(test):
import string
return not (set(test) - set(string.digits))
'-+ '
和结尾的.0
、E-1
,那么set(input_string) == set(string.digits)
。 - jfsfloat(number)==float(number)//1
(u.isdecimal() and u.isascii())
Python <= 3.6:(u.isdecimal() and u == str(int(u)))
其他答案建议使用 .isdigit()
或 .isdecimal()
,但这些方法both include some upper-unicode characters,例如'٢'
(u'\u0662'
)。u = u'\u0662' # '٢'
u.isdigit() # True
u.isdecimal() # True
u.isascii() # False (Python 3.7+ only)
u == str(int(u)) # False
int()
函数可以很好地处理它们。 - ShadowRanger我理解您想要检查字符串是否可以转换为整数。为了做到这一点,您可以:
def is_string_convertable_to_int(value: str) -> bool:
return value.replace('-', '').isdigit()
顺便说一句,您可以轻松修改此函数以检查字符串是否可转换为浮点数,只需添加 replace('.', '') 并使用 value.count('.') = 1 检查一个 '.' 是否存在。
检查整数后将值转换为字符串,然后检查字符串的第一个字符值是-
或+
,并且其余部分是isdigit
。最后只需检查isdigit
。
test = ['1','12015','1..2','a2kk78','1.5',2,1.24,'-8.5','+88751.71','-1','+7']
检查
for k,v in enumerate(test):
print(k, v, 'test: ', True if isinstance(v, int) is not False else True if str(v)[0] in ['-', '+'] and str(v)[1:].isdigit() else str(v).isdigit())
结果
0 1 test: True
1 12015 test: True
2 1..2 test: False
3 a2kk78 test: False
4 1.5 test: False
5 2 test: True
6 1.24 test: False
7 -8.5 test: False
8 +88751.71 test: False
9 -1 test: True
10 +7 test: True