如何在 Python 中的 isdigit()、isdecimal() 和 isnumeric() 之间进行选择
在这篇文章中,您将了解 Python 3 中str.isdigit、str.isdecimal和str.isnumeric之间的细微差别,以及如何选择最适合工作的一个。 在处理字符串时,通常通过从某个来源读取它们,您可能想要检查给定的字符串是否为数字。字符串类 (str) 带有 3 种不同的方法,您可以使用它们来实现该目的。 它们每个都有优缺点,区分它们之间的差异将为您节省大量的开发和调试时间。
在这篇文章中,您将了解 Python 3 中str.isdigit
、str.isdecimal
和str.isnumeric
之间的细微差别,以及如何选择最适合工作的一个。
在处理字符串时,通常通过从某个来源读取它们,您可能想要检查给定的字符串是否为数字。字符串类 (str
) 带有 3 种不同的方法,您可以使用它们来实现该目的。
它们每个都有优缺点,区分它们之间的差异将为您节省大量的开发和调试时间。
在本文中,您将:
-
了解
str.isdigit()
、str.isdecimal()
和str.isnumeric()
的作用、它们的局限性、如何使用它们以及何时应该使用它们 -
了解
isdigit
vsisnumeric
vsisdecimal
的区别区别 -
了解为什么
isdigit
、isnumeric
或isdecimal
不适合您 -
如何解决用它们不容易解决的常见问题,例如:
-
如何确保浮点数字符串是数字
-
如何使用带负数的
isdigit
、isnumeric
或isdecimal
目录
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
不是函数而是str
、bytes
和bytearray
类中的一个方法。
这对于这些更简单的情况很有效,但是如果字符串有空格会发生什么?
# ' ' (space) is not a digit
In [8]: ' 102030'.isdigit()
Out[8]: False
这失败了,因为字符串在开头包含一个空格。因此,我们不能按原样使用它来读取未处理的源,例如input()
函数。在使用isdigit()
检查之前,您必须始终记住对输入进行预处理。这可能是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
事实证明确实如此!您实际上可以将它与input()
一起使用:
>>> a = input('Enter a number:')
Enter a number:2⁷
>>> a
'2⁷'
>>> a.isdigit()
True
即使它适用于上标,它也不能处理分数字符。这种方法实际上是关于个位数的。
# fractions in Unicode are not digits
>>> '⅕'.isdigit()
False
正如我们所看到的,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))
下图显示了其中一些测试用例。
str.isdigit() 非常适用于数字 Unicode
不接受不代表数字的 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
还接受 Unicode 字符,这些字符用于在其他语言中以 10 为基数形成数字。例如,阿拉伯-印度数字零被视为小数,因此'٠'.isdecimal()
返回 true。
>>> '٠'.isdecimal()
True
阿拉伯语-印度语,例如 '٠' 以 10 为底的十进制数
什么时候使用?
当您要验证字符串中的每个字符是否可以形成以 10 为底的数字时,请使用str.isdecimal
。由于标点、上标、字母和减号不是小数,它们将返回False
。
isnumeric()
的工作原理和使用时机
这个与isdigit
和isdecimal
有很大的重叠。根据文档,如果所有字符串都是数字且不能为空,则isnumeric
返回True
。
这里的关键区别是_numeric_这个词。 numeric 字符和 digit 字符有什么区别?
不同之处在于,数字是单个 Unicode 值,而数字字符是表示数值的任何 Unicode 符号,包括分数!
不仅如此,isnumeric
还可以很好地处理罗马数字!
让我们看看一些实际的例子。
>>> '⅕'.isdigit()
False
>>> '⅕'.isnumeric()
True
>>> '⁵'.isnumeric()
True
'5⁵'.isnumeric()
True
>>> '-4'.isnumeric()
False
>>> '4.5'.isnumeric()
False
>>> '5 '.isnumeric()
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
什么时候使用?
当您想要验证字符串中的每个字符是否都是有效的数字字符时,请使用str.isnumeric
,包括分数、上标和罗马数字。由于标点符号、字母和减号不是数值,它们的计算结果为False
。
解决常见问题
在本节中,我们将了解如何解决使用isdigit
、isnumeric
和isdecimal
时最常见的问题。
如何判断浮点数是否为数字?
最好的检查方法是尝试将其转换为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
结论
在这篇文章中,我们看到了isdigit
与isdecimal
与isnumeric
之间的细微差别,以及如何为您的用例选择最合适的字符串方法。我们还看到了无法单独处理的案例以及如何克服这些限制。
这就是今天的内容,我希望你喜欢这篇文章!
参考:
docs.python.org/3/library/stdtypes.html
fileformat.info/info/unicode/char/0660/brow..
stackoverflow.com/a/7643705
stackoverflow.com/a/28279773
更多推荐
所有评论(0)