在这篇文章中,您将了解 Python 3 中str.isdigitstr.isdecimalstr.isnumeric之间的细微差别,以及如何选择最适合工作的一个。

在处理字符串时,通常通过从某个来源读取它们,您可能想要检查给定的字符串是否为数字。字符串类 (str) 带有 3 种不同的方法,您可以使用它们来实现该目的。

它们每个都有优缺点,区分它们之间的差异将为您节省大量的开发和调试时间。

在本文中,您将:

  • 了解str.isdigit()str.isdecimal()str.isnumeric()的作用、它们的局限性、如何使用它们以及何时应该使用它们

  • 了解isdigitvsisnumericvsisdecimal的区别区别

  • 了解为什么isdigitisnumericisdecimal不适合您

  • 如何解决用它们不容易解决的常见问题,例如:

  • 如何确保浮点数字符串是数字

  • 如何使用带负数的isdigitisnumericisdecimal

目录

1.isdigit()的工作原理和使用时机

2.isdecimal()的工作原理和使用时机

3.isnumeric()的工作原理和使用时机

4.解决常见问题

4.1。如何判断浮点数是否为数字?

4.2.如何判断负数是否为数字?

4.3.为什么isdigit不适合我?

5.结论

isdigit()的工作原理和使用时机

str.isdigit()是最明显的选择,如果您想确定一个字符串 - 还是一个字符 - 在 Python 中是一个数字。

根据其文档,如果字符串中的所有字符都是数字且不为空,则此方法返回True,否则将返回False。让我们看一些例子:

# all characters in the string are digits
>>> '102030'.isdigit()
True

# 'a' is not a digit
>>> '102030a'.isdigit()
False

# isdigit fails if there's whitespace
>>> ' 102030'.isdigit()
False

# it must be at least one char long
>>> ''.isdigit()
False

# dots '.' are also not digit
>>> '12.5'.isdigit()
False

不像很多人想象的那样,isdigit不是函数而是strbytesbytearray类中的一个方法。

这对于这些更简单的情况很有效,但是如果字符串有空格会发生什么?

# ' ' (space) is not a digit
In [8]: ' 102030'.isdigit()
Out[8]: False

这失败了,因为字符串在开头包含一个空格。因此,我们不能按原样使用它来读取未处理的源,例如input()函数。在使用isdigit()检查之前,您必须始终记住对输入进行预处理。这可能是isdigit不适合您的原因之一。

python str isdigit 如何处理整数和浮点数

>>> a = input('Enter a number: ')
Enter a number: 56 

>>> a
'56 '

>>> a.isdigit()
False

>>> a.strip()
'56'

>>> a.strip().isdigit()
True

尽管有这种严格的行为,isdigit还是有一些问题。如果我们仔细阅读文档,它说该方法还可以处理“上标数字”。

数字包括十进制字符和需要特殊处理的数字,例如兼容性上标数字。

但这是如何工作的?它会为带有上标的字符串(例如 27)返回True吗?

>>> d = '2' + '\u2077'

>>> d
'2⁷'

>>> d.isdigit()
True

# it accepts superscripts only
>>> '⁵'.isdigit()
True

# and superscripts first followed by a number
>>> '⁵5'.isdigit()
True

python isdigit如何处理上标字符

事实证明确实如此!您实际上可以将它与input()一起使用:

>>> a = input('Enter a number:')
Enter a number:2⁷

>>> a
'2⁷'

>>> a.isdigit()
True

即使它适用于上标,它也不能处理分数字符。这种方法实际上是关于个位数的。

# fractions in Unicode are not digits
>>> '⅕'.isdigit()
False

图像显示了 python isdigit 如何处理 unicode 中的分数字符

正如我们所看到的,str.isdigit()非常适用于 Unicode 字符。如果我们看一下这个方法的单元测试套件,我们可以看到一些有趣的测试用例。

# https://github.com/python/cpython/blob/3.10/Lib/test/test_unicode.py#L704
    def test_isdigit(self):
        super().test_isdigit()
        self.checkequalnofix(True, '\u2460', 'isdigit')
        self.checkequalnofix(False, '\xbc', 'isdigit')
        self.checkequalnofix(True, '\u0660', 'isdigit')

        for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E',
                   '\U0001F40D', '\U0001F46F', '\U00011065']:
            self.assertFalse(ch.isdigit(), '{!a} is not a digit.'.format(ch))
        for ch in ['\U0001D7F6', '\U00011066', '\U000104A0', '\U0001F107']:
            self.assertTrue(ch.isdigit(), '{!a} is a digit.'.format(ch))

下图显示了其中一些测试用例。

图片显示了 python isdigit 如何处理 unicode 数字

str.isdigit() 非常适用于数字 Unicode

图像显示 isdigit 不能使用非数值

不接受不代表数字的 Unicode 字符

总结isdigit不能做什么

它可以处理空格吗?

它可以处理十六进制吗?

它会引发异常吗?

它是否接受负数(带减号)?

什么时候使用?

当您要验证字符串中的每个字符都是单个数字时,请使用str.isdigit,即不是标点符号,不是字母,也不是负数。

isdecimal()的工作原理和使用时机

str.isdecimal()方法非常相似,如果所有字符都是十进制字符并且字符串不为空,则返回True。这意味着上标是_NOT_十进制数字,因此它们将返回False

>>> '5'.isdecimal()
True

>>> '⁵'.isdecimal()
False

>>> '5⁵'.isdecimal()
False

>>> '-4'.isdecimal()
False

>>> '4.5'.isdecimal()
False

isdecimal 不能接受上标

上标不是十进制数

isdecimal还接受 Unicode 字符,这些字符用于在其他语言中以 10 为基数形成数字。例如,阿拉伯-印度数字零被视为小数,因此'٠'.isdecimal()返回 true。

>>> '٠'.isdecimal()
True

python isdecimal 为基数为 10 的阿拉伯印度数字返回 true

阿拉伯语-印度语,例如 '٠' 以 10 为底的十进制数

什么时候使用?

当您要验证字符串中的每个字符是否可以形成以 10 为底的数字时,请使用str.isdecimal。由于标点、上标、字母和减号不是小数,它们将返回False

isnumeric()的工作原理和使用时机

这个与isdigitisdecimal有很大的重叠。根据文档,如果所有字符串都是数字且不能为空,则isnumeric返回True

这里的关键区别是_numeric_这个词。 numeric 字符和 digit 字符有什么区别?

不同之处在于,数字是单个 Unicode 值,而数字字符是表示数值的任何 Unicode 符号,包括分数!

不仅如此,isnumeric还可以很好地处理罗马数字!

让我们看看一些实际的例子。

>>> '⅕'.isdigit()
False

>>> '⅕'.isnumeric()
True

>>> '⁵'.isnumeric()
True

'5⁵'.isnumeric()
True

python的isumeric方法返回true的几个例子

>>> '-4'.isnumeric()
False

>>> '4.5'.isnumeric()
False

>>> '5 '.isnumeric()
False

isumeric 以浮点数或负数返回 false

# ⅮⅪ in roman numerals in unicode and represent 511 in base10
>>> 'ⅮⅪ'.isnumeric()
True

# Roman numerals are not digits
>>> 'ⅮⅪ'.isdigit()
False

# Ascii letters 'D', 'X', and 'I' are not numeric
>>> 'DXI'.isnumeric()
False

isumeric 适用于罗马数字

什么时候使用?

当您想要验证字符串中的每个字符是否都是有效的数字字符时,请使用str.isnumeric,包括分数、上标和罗马数字。由于标点符号、字母和减号不是数值,它们的计算结果为False

解决常见问题

在本节中,我们将了解如何解决使用isdigitisnumericisdecimal时最常见的问题。

如何判断浮点数是否为数字?

最好的检查方法是尝试将其转换为float

如果float构造函数没有引发任何异常,则该字符串是有效的浮点数。这是一个名为 EAFP 的pythonic 成语(比许可更容易请求宽恕)。

def is_float_digit(n: str) -> bool:
     try:
         float(n)
         return True
     except ValueError:
         return False

>>> is_float_digit('23.45')
True

>>> is_float_digit('23.45a')
False

注意:此字符串方法不适用于上标!验证这一点的唯一方法是将替换为“.”。然后调用 `isdigit()' 就可以了。

>>> is_float_digit('23.45⁵')
False
def is_float_digit_v2(n: str) -> bool:
     return n.replace('.', '', 1).isdigit()

>>> is_float_digit_v2('23.45⁵')
True

如何判断负数是否为数字?

检查以减号开头的数字取决于目标类型。

由于我们在这里讨论的是数字,因此断言字符串是否可以转换为int是有意义的。这与为浮点数讨论的 EAFP 方法非常相似。

但是,就像前面的方法一样,它不处理上标。

def is_negative_number_digit(n: str) -> bool:
     try:
         int(n)
         return True
     except ValueError:
         return False

>>> is_negative_number_digit('-2345')
True

>>> is_negative_number_digit('-2345⁵')
False

要解决这个问题,最好的方法是去掉减号。

def is_negative_number_digit_v2(n: str) -> bool:
     return n.lstrip('-').isdigit()

>>> is_negative_number_digit_v2('-2345')
True

>>> is_negative_number_digit_v2('-2345⁵')
True

为什么isdigit不适合我?

阻止isdigit/isnumeric/isdecimal正常工作的最常见问题是字符串中有前导或尾随空格。在使用它们之前,必须删除任何前导或尾随空格,或其他字符,例如换行符 (\n)。

>>> ' 54'.isdigit()
False

>>> ' 54'.strip().isdigit()
True

>>> ' 54'.isnumeric()
False

>>> ' 54'.strip().isnumeric()
True

>>> ' 54'.isdecimal()
False

>>> ' 54'.strip().isdecimal()
True

>>> '65\n'.isdigit()
False

>>> '65\n'.strip().isdigit()
True

结论

在这篇文章中,我们看到了isdigitisdecimalisnumeric之间的细微差别,以及如何为您的用例选择最合适的字符串方法。我们还看到了无法单独处理的案例以及如何克服这些限制。

这就是今天的内容,我希望你喜欢这篇文章!

参考:

docs.python.org/3/library/stdtypes.html

fileformat.info/info/unicode/char/0660/brow..

stackoverflow.com/a/7643705

stackoverflow.com/a/28279773

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐