有没有办法告诉一个字符串是否代表一个整数(例如,'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
当前回答
我猜这个问题与速度有关,因为try/except有一个时间惩罚:
测试数据
首先,我创建了一个包含200个字符串、100个失败字符串和100个数字字符串的列表。
from random import shuffle
numbers = [u'+1'] * 100
nonumbers = [u'1abc'] * 100
testlist = numbers + nonumbers
shuffle(testlist)
testlist = np.array(testlist)
numpy解决方案(仅适用于数组和unicode)
Np.core.defchararray.isnumeric也可以用于unicode字符串,但它返回一个数组。所以,如果你必须做成千上万的转换,并且有丢失的数据或非数值数据,这是一个很好的解决方案。
import numpy as np
%timeit np.core.defchararray.isnumeric(testlist)
10000 loops, best of 3: 27.9 µs per loop # 200 numbers per loop
试/除了
def check_num(s):
try:
int(s)
return True
except:
return False
def check_list(l):
return [check_num(e) for e in l]
%timeit check_list(testlist)
1000 loops, best of 3: 217 µs per loop # 200 numbers per loop
numpy解决方案似乎更快。
其他回答
我有一种可能根本不使用int,除非字符串不代表数字,否则不应该引发异常
float(number)==float(number)//1
它应该适用于任何类型的字符串,float接受,正,负,工程符号…
对于正整数,可以使用.isdigit:
>>> '16'.isdigit()
True
但它对负整数不起作用。假设您可以尝试以下方法:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
它不适用于'16.0'格式,在这个意义上,'16.0'格式类似于int类型强制转换。
编辑:
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
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
如果你想只接受低ascii码的数字,这里有这样做的测试:
Python 3.7+:(u.isdecimal() and u.isascii()))
Python <= 3.6:(u.isdecimal() and u == str(int(u)))
其他答案建议使用.isdigit()或.isdecimal(),但它们都包含一些上unicode字符,如'缌' (u'\u0662'):
u = u'\u0662' # '٢'
u.isdigit() # True
u.isdecimal() # True
u.isascii() # False (Python 3.7+ only)
u == str(int(u)) # False
我用的最简单的方法
def is_int(item: str) -> bool:
return item.lstrip('-+').isdigit()