web-dev-qa-db-fra.com

Quelle est la différence entre str.isdigit, isnumeric et isdecimal en python?

Quand je lance ces méthodes

s.isdigit()
s.isnumeric()
s.isdecimal()

J'ai toujours eu comme sortie ou tout Vrai, ou tout Faux pour chaque valeur de s (qui est bien sûr une chaîne). Quelle est la différence entre les trois? Pouvez-vous donner un exemple qui donne deux vrais et un faux (ou vice-versa)?

41
user8225026

Cela concerne principalement les classifications Unicode. Voici quelques exemples montrant les divergences:

>>> def spam(s):
...     for attr in 'isnumeric', 'isdecimal', 'isdigit':
...         print(attr, getattr(s, attr)())
...         
>>> spam('½')
isnumeric True
isdecimal False
isdigit False
>>> spam('³')
isnumeric True
isdecimal False
isdigit True

Un comportement spécifique est dans la documentation officielle ici .

Script pour les trouver tous:

import sys
import unicodedata
from collections import defaultdict

d = defaultdict(list)
for i in range(sys.maxunicode + 1):
    s = chr(i)
    t = s.isnumeric(), s.isdecimal(), s.isdigit()
    if len(set(t)) == 2:
        try:
            name = unicodedata.name(s)
        except ValueError:
            name = f'codepoint{i}'
        print(s, name)
        d[t].append(s)
42
wim

La documentation Python) indique la différence entre les trois méthodes.

str.isdigit

Renvoie true si tous les caractères de la chaîne sont des chiffres et s'il y a au moins un caractère, false sinon. Les chiffres incluent les caractères décimaux et ceux qui nécessitent un traitement spécial, tels que les chiffres en exposant de compatibilité. Cela couvre les chiffres qui ne peuvent pas être utilisés pour former des nombres en base 10, comme les nombres de Kharosthi. Formellement, un chiffre est un caractère dont la valeur de propriété est Numeric_Type = Digit ou Numeric_Type = Decimal .

str.isnumeric

Renvoie true si tous les caractères de la chaîne sont des caractères numériques et s'il y a au moins un caractère, false sinon. Les caractères numériques incluent les caractères numériques et tous les caractères qui possèdent la propriété de valeur numérique Unicode, par exemple. U + 2155, FRACTION VULGARE UNE CINQUIÈME. Formellement, les caractères numériques sont ceux avec la valeur de propriété Numeric_Type = Digit, Numeric_Type = Decimal ou Numeric_Type = Numeric .

str.isdecimal

Renvoie true si tous les caractères de la chaîne sont des caractères décimaux et qu'il y a au moins un caractère, false sinon. Les caractères décimaux sont ceux qui peuvent être utilisés pour former des nombres en base 10, par exemple. U + 0660, CHIFFRE ZÉRO ARABE-INDIQUE Formellement, un caractère décimal est un caractère de la catégorie générale Unicode "Nd" .


Comme @Wim l'a dit, la principale différence entre les trois méthodes réside dans la manière dont elles gèrent des caractères Unicode spécifiques.

25
Christian Dean

Par définition, isdecimal()isdigit()isnumeric(). Autrement dit, si une chaîne est decimal, alors il s'agira également de digit et numeric.

Par conséquent, étant donné la chaîne s et la tester avec ces trois méthodes, il n’y aura que 4 types de résultats.

+-------------+-----------+-------------+----------------------------------+
| isdecimal() | isdigit() | isnumeric() |          Example                 |
+-------------+-----------+-------------+----------------------------------+
|    True     |    True   |    True     | "038", "੦੩੮", "038"           |
|  False      |    True   |    True     | "⁰³⁸", "????⒊⒏", "⓪③⑧"          |
|  False      |  False    |    True     | "↉⅛⅘", "ⅠⅢⅧ", "⑩⑬㊿", "壹貳參"  |
|  False      |  False    |  False      | "abc", "38.0", "-38"             |
+-------------+-----------+-------------+----------------------------------+

1. Quelques exemples de caractères isdecimal()==True

(ainsi isdigit()==True et isnumeric()==True)

"0123456789"  DIGIT ZERO~NINE
"٠١٢٣٤٥٦٧٨٩"  ARABIC-INDIC DIGIT ZERO~NINE
"०१२३४५६७८९"  DEVANAGARI DIGIT ZERO~NINE
"০১২৩৪৫৬৭৮৯"  BENGALI DIGIT ZERO~NINE
"੦੧੨੩੪੫੬੭੮੯"  GURMUKHI DIGIT ZERO~NINE
"૦૧૨૩૪૫૬૭૮૯"  GUJARATI DIGIT ZERO~NINE
"୦୧୨୩୪୫୬୭୮୯"  ORIYA DIGIT ZERO~NINE
"௦௧௨௩௪௫௬௭௮௯"  TAMIL DIGIT ZERO~NINE
"౦౧౨౩౪౫౬౭౮౯"  TELUGU DIGIT ZERO~NINE
"೦೧೨೩೪೫೬೭೮೯"  KANNADA DIGIT ZERO~NINE
"൦൧൨൩൪൫൬൭൮൯"  MALAYALAM DIGIT ZERO~NINE
"๐๑๒๓๔๕๖๗๘๙"  THAI DIGIT ZERO~NINE
"໐໑໒໓໔໕໖໗໘໙"  LAO DIGIT ZERO~NINE
"༠༡༢༣༤༥༦༧༨༩"  TIBETAN DIGIT ZERO~NINE
"၀၁၂၃၄၅၆၇၈၉"  MYANMAR DIGIT ZERO~NINE
"០១២៣៤៥៦៧៨៩"  KHMER DIGIT ZERO~NINE
"0123456789"  FULLWIDTH DIGIT ZERO~NINE
"????????????????????????????????????????"  MATHEMATICAL BOLD DIGIT ZERO~NINE
"????????????????????????????????????????"  MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO~NINE
"????????????????????????????????????????"  MATHEMATICAL SANS-SERIF DIGIT ZERO~NINE
"????????????????????????????????????????"  MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO~NINE
"????????????????????????????????????????"  MATHEMATICAL MONOSPACE DIGIT ZERO~NINE

2. Quelques exemples de caractères isdecimal()==False mais isdigit()==True

(donc isnumeric()==True)

"⁰¹²³⁴⁵⁶⁷⁸⁹"  SUPERSCRIPT ZERO~NINE
"₀₁₂₃₄₅₆₇₈₉"  SUBSCRIPT ZERO~NINE
"????⒈⒉⒊⒋⒌⒍⒎⒏⒐"  DIGIT ZERO~NINE FULL STOP
"????????????????????????????????????????"  DIGIT ZERO~NINE COMMA
"⓪①②③④⑤⑥⑦⑧⑨"  CIRCLED DIGIT ZERO~NINE
"⓿❶❷❸❹❺❻❼❽❾"  NEGATIVE CIRCLED DIGIT ZERO~NINE
"⑴⑵⑶⑷⑸⑹⑺⑻⑼"  PARENTHESIZED DIGIT ONE~NINE
"➀➁➂➃➄➅➆➇➈"  Dingbat CIRCLED SANS-SERIF DIGIT ONE~NINE
"⓵⓶⓷⓸⓹⓺⓻⓼⓽"  DOUBLE CIRCLED DIGIT ONE~NINE
"➊➋➌➍➎➏➐➑➒"  Dingbat NEGATIVE CIRCLED SANS-SERIF DIGIT ONE~NINE
"፩፪፫፬፭፮፯፰፱"  ETHIOPIC DIGIT ONE~NINE

. Quelques exemples de caractères isdecimal()==False et isdigit()==False mais isnumeric()==True

"½⅓¼⅕⅙⅐⅛⅑⅒⅔¾⅖⅗⅘⅚⅜⅝⅞⅟↉"  VULGAR FRACTION
"৴৵৶৷৸৹"  BENGALI CURRENCY NUMERATOR
"௰௱௲"  TAMIL NUMBER TEN, ONE HUNDRED, ONE THOUSAND
"౸౹౺౻౼౽౾"  TELUGU FRACTION DIGIT
"൰൱൲൳൴൵"  MALAYALAM NUMBER, MALAYALAM FRACTION
"༳༪༫༬༭༮༯༰༱༲"  TIBETAN DIGIT HALF ZERO~NINE
"፲፳፴፵፶፷፸፹፺፻፼"  ETHIOPIC NUMBER TEN~NINETY, HUNDRED, TEN THOUSAND
"៰៱៲៳៴៵៶៷៸៹"  KHMER SYMBOL LEK ATTAK
"ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯ"  ROMAN NUMERAL
"ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿ"  SMALL ROMAN NUMERAL
"ↀↁↂↅↆ"  ROMAN NUMERAL
"⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿"  CIRCLED NUMBER TEN~FIFTY
"㉈㉉㉊㉋㉌㉍㉎㉏"  CIRCLED NUMBER TEN~EIGHTY ON BLACK SQUARE
"⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇"  PARENTHESIZED NUMBER TEN~TWENTY
"⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛"  NUMBER TEN~TWENTY FULL STOP
"⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴"  NEGATIVE CIRCLED NUMBER ELEVEN
"⓾➉❿➓"  various styles of CIRCLED NUMBER TEN
"????"  Dingbat NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
"〇"  IDEOGRAPHIC NUMBER ZERO
"〡〢〣〤〥〦〧〨〩〸〹〺"  HANGZHOU NUMERAL ONE~TEN, TWENTY, THIRTY
"㆒㆓㆔㆕"  IDEOGRAPHIC ANNOTATION ONE~FOUR MARK
"㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩"  PARENTHESIZED IDEOGRAPH ONE~TEN
"㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉"  CIRCLED IDEOGRAPH ONE~TEN
"一二三四五六七八九十壹貳參肆伍陸柒捌玖拾零百千萬億兆弐貮贰㒃㭍漆什㐅陌阡佰仟万亿幺兩㠪亖卄卅卌廾廿"  CJK UNIFIED IDEOGRAPH
"參拾兩零六陸什"  CJK COMPATIBILITY IDEOGRAPH
"????????????????????????????????????????????????????????????????????????"  AEGEAN NUMBER ONE~NINE, TEN~NINETY
"????????????????????????????????????????????????????????????????????????"  AEGEAN NUMBER ONE~NINE HUNDRED, ONE~NINE THOUSAND
"????????????????????????????????"  AEGEAN NUMBER TEN~NINETY THOUSAND
"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"  GREEK ACROPHONIC ATTIC
"????????????????????????????????????"  COUNTING ROD UNIT DIGIT ONE~NINE
"????????????????????????????????????"  COUNTING ROD TENS DIGIT ONE~NINE
12
AnnieFromTaiwan

un nombre négatif a = "-10" serait faux pour chacun de ces trois

a.isdecimal(), a.isdigit(), a.isnumeric()

sont False, False, False isdecimal () n'aura que 0 à 9 dans toutes les langues, mais sans signes négatifs isdigit () n'aura que 0 à 9 dans toutes les langues, également dans les positions "au pouvoir". (nombres décimaux au pouvoir, ex: 2 à la puissance de 5). isnumeric () est encore plus large spectre .. il inclura également plus de 0 à 9 dans n'importe quelle position, mais il aura aussi des dizaines, des centaines, des milliers dans n'importe quelle langue, ex. roman 10 est X, c’est un isnumérique valide (). Mais tous les trois sont faux pour: Les nombres négatifs, ex: -10 et les nombres en virgule flottante, ex: 10.1

0
Sree