有没有办法告诉一个字符串是否代表一个整数(例如,'3','-17'但不是'3.14'或'asfasfas')而不使用try/except机制?

is_int('3.14') == False
is_int('-7')   == 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

其他回答

使用正则表达式:

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()只编译正则表达式一次。

我真的很喜欢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

使用普通2.7 python:

$ python --version
Python 2.7.10

我添加的两个测试用例(isInt_loop和isInt_digit)都通过了完全相同的测试用例(它们都只接受无符号整数),但我认为人们可以更聪明地修改字符串实现(isInt_loop)而不是内置的isdigit()函数,所以我包括了它,尽管执行时间略有不同。(这两种方法都比其他方法好很多,但没有处理额外的东西:“。/ + / -)

此外,我发现有趣的是,regex (isInt_re2方法)在2012年(目前是2018年)由Shavais执行的相同测试中击败了字符串比较。也许正则表达式库已经改进了?

呃. .试试这个:

def int_check(a):
    if int(a) == a:
        return True
    else:
        return False

如果你不输入非数字的字符串,这是可行的。

还有(我忘了写数字检查部分了。),有一个函数检查字符串是否是数字。它是str.isdigit()。这里有一个例子:

a = 2
a.isdigit()

如果调用a.s isdigit(),它将返回True。

我的建议如下:

import ast

def is_int(s):
    return isinstance(ast.literal_eval(s), int)

从文档中可以看出:

安全地计算表达式节点或包含Python文字或容器显示的字符串。提供的字符串或节点只能由以下Python文字结构组成:字符串、字节、数字、元组、列表、字典、集、布尔值和None。

我应该指出,当对任何不构成Python文字的内容调用时,这将引发ValueError异常。因为这个问题要求一个没有try/except的解决方案,我有一个Kobayashi-Maru类型的解决方案:

from ast import literal_eval
from contextlib import suppress

def is_int(s):
    with suppress(ValueError):
        return isinstance(literal_eval(s), int)
    return False

¯\_(五)_/¯

我一直这样做,我对使用try/except模式有一种温和但不可否认的非理性厌恶。我用这个:

all([xi in '1234567890' for xi in x])

它不包含负数,所以你可以去掉左边所有的负号,然后检查结果是否包含0-9之间的数字:

all([xi in '1234567890' for xi in x.lstrip('-')])

如果你不确定输入是字符串,你也可以将x传递给str():

all([xi in '1234567890' for xi in str(x).lstrip('-')])

有一些(边缘?)情况下,这是行不通的:

It doesn't work for various scientific and/or exponential notations (e.g. 1.2E3, 10^3, etc.) - both will return False. I don't think other answers accommodated this either, and even Python 3.8 has inconsistent opinions, since type(1E2) gives <class 'float'> whereas type(10^2) gives <class 'int'>. An empty string input gives True. A leading plus sign (e.g. "+7") gives False. Multiple minus signs are ignored so long as they're leading characters. This behavior is similar to the python interpreter* in that type(---1) returns <class int>. However, it isn't completely consistent with the interpreter in that int('---1') gives an error, but my solution returns True with the same input.

所以它不会对所有可能的输入都有效,但如果你能排除这些,这是一个OK的单行检查,如果x不是整数返回False,如果x是整数返回True。但是如果你真的想要精确模拟int()内置的行为,你最好使用try/except。

我不知道这是否是python式的,但它只有一行,而且代码的功能相对清晰。

我并不是说解释器忽略了前导负号,只是说任何数量的前导负号都不会改变结果是整数。Int(——1)实际上被解释为-(-1)或1。Int(——1)被解释为-(-(-1)),或者-1。所以前面有偶数个负号就会得到一个正整数,前面有奇数个负号就会得到一个负整数,但结果总是整数。