194 votes

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

Lorsque j'exécute ces méthodes

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

J'obtiens toujours en sortie soit tout Vrai, soit tout Faux pour chaque valeur de s (qui est bien sûr une chaîne de caractères). Quelle est la différence entre les trois? Pouvez-vous fournir un exemple qui donne deux Vrai et un Faux (ou vice versa)?

226voto

AnnieFromTaiwan Points 647

Par définition, isdecimal() isdigit() isnumeric(). Autrement dit, si une chaîne est décimale, alors elle sera aussi digit et numérique.

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

+-------------+-----------+-------------+----------------------------------+
| isdecimal() | isdigit() | isnumeric() |          Exemple                 |
+-------------+-----------+-------------+----------------------------------+
|    Vrai     |    Vrai   |    Vrai     | "038", "", ""           |
|  Faux      |    Vrai   |    Vrai     | "³", "", ""          |
|  Faux      |  Faux    |    Vrai     | "", "", "", ""  |
|  Faux      |  Faux    |  Faux      | "abc", "38.0", "-38"             |
+-------------+-----------+-------------+----------------------------------+

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

(donc isdigit()==Vrai et isnumeric()==Vrai)

"0123456789"  CHIFFRE ZÉRO~NEUF
""  CHIFFRE ARABE ZÉRO~NEUF
""  CHIFFRE DÉVANÂGARÎ ZÉRO~NEUF
""  CHIFFRE BENGALI ZÉRO~NEUF
""  CHIFFRE GURMUKHI ZÉRO~NEUF
""  CHIFFRE GUJARATI ZÉRO~NEUF
""  CHIFFRE ORIYA ZÉRO~NEUF
""  CHIFFRE TAMOUL ZÉRO~NEUF
""  CHIFFRE TÉLOUGOU ZÉRO~NEUF
""  CHIFFRE KANNADA ZÉRO~NEUF
""  CHIFFRE MALAYALAM ZÉRO~NEUF
""  CHIFFRE THAÏ ZÉRO~NEUF
""  CHIFFRE LAO ZÉRO~NEUF
""  CHIFFRE TIBÉTAIN ZÉRO~NEUF
""  CHIFFRE MYANMAR ZÉRO~NEUF
""  CHIFFRE KHMER ZÉRO~NEUF
""  CHIFFRE À LARGEUR FIXE ZÉRO~NEUF
""  CHIFFRE GRAS MATHÉMATIQUE ZÉRO~NEUF
""  CHIFFRE DOUBLE À DOUBLE BARRE ZÉRO~NEUF
""  CHIFFRE SANS EMPATTEMENT MATHÉMATIQUE ZÉRO~NEUF
""  CHIFFRE GRAS SANS EMPATTEMENT MATHÉMATIQUE ZÉRO~NEUF
""  CHIFFRE MONOSPACE MATHÉMATIQUE ZÉRO~NEUF

2. Quelques exemples de caractères isdecimal()==Faux mais isdigit()==Vrai

(donc isnumeric()==Vrai)

"¹²³"  ZÉRO SUPERSCRIPT~NEUF
""  ZÉRO SUBSCRIPT~NEUF
""  CHIFFRE ZÉRO~NEUF POINT
""  CHIFFRE ZÉRO~NEUF VIRGULE
""  CHIFFRE CERCLÉ ZÉRO~NEUF
""  CHIFFRE CERCLÉ NÉGATIF ZÉRO~NEUF
""  CHIFFRE PARENTHÉSÉ UN~NEUF
""  CHIFFRE SANS EMPATTEMENT CERCLÉ UN~NEUF
""  CHIFFRE DOUBLE CERCLÉ UN~NEUF
""  CHIFFRE SANS EMPATTEMENT CERCLÉ NÉGATIF UN~NEUF
""  CHIFFRE ÉTHIOPIEN UN~NEUF

3. Quelques exemples de caractères isdecimal()==Faux et isdigit()==Faux mais isnumeric()==Vrai

"½¼¾"  FRACTION VULGAIRE
""  NUMÉRATEUR MONÉTAIRE BENGALI
""  NOMBRE TAMIL DIX, CENT, MILLE
""  CHIFFRE DE FRACTION TÉLOUGOU
""  NOMBRE MALAYALAM, FRACTION MALAYALAME
""  CHIFFRE TIBÉTAIN DEMI ZÉRO~NEUF
""  NOMBRE ÉTHIOPIEN DIX~QUATRE-VINGT-DIX, CENT, DIX MILLE
""  SYMBOLE KHMER LEK ATTAK
""  NOMBRE ROMAIN
""  PETIT NOMBRE ROMAIN
""  NOMBRE ROMAIN
""  CHIFFRE CERCLÉ DIX~CINQUANTE
""  CHIFFRE CERCLÉ DIX~QUATRE-VINGT SUR CARRÉ NOIR
""  NOMBRE EN PARENTHÈSES DIX~VINGT
""  CHIFFRE DIX~VINGT POINT
""  CHIFFRE CERCLÉ NÉGATIF ONZE
""  différents styles de CHIFFRE CERCLÉ DIX
""  CHIFFRE SANS EMPATTEMENT CERCLÉ NÉGATIF ZÉRO
""  IDÉOGRAMME CHIFFRE ZÉRO
""  CHIFFRE HANGZHOU UN~DIX, VINGT, TRENTE
""  MARQUAGE IDÉOGRAMME UN~QUATRE
""  IDÉOGRAMME EN PARENTHÈSE UN~DIX
""  IDÉOGRAMME CERCLÉ UN~DIX
""  IDÉOGRAMME UNIFIÉ CJC
""  IDÉOGRAMME DE COMPATIBILITÉ CJC
""  NOMBRE ÉGÉEN UN~NEUF, DIX~QUATRE-VINGT-DIX
""  NOMBRE ÉGÉEN CENT UN~NEUF CENT, UN~NEUF MILLE
""  NOMBRE ÉGÉEN DIX~QUATRE-VINGT-DIX MILLE
""  Grec ACROPHONIQUE ATTIC
""  UNITÉ DE CHIFFRE DE BÂTON DE COMPTAGE UN~NEUF
""  DIZAINE DE CHIFFRE DE BÂTON DE COMPTAGE UN~NEUF

8 votes

"" m'a vraiment désorienté, car je pensais que c'était juste "0.3.8.". Ce n'est qu'après l'avoir copié-collé dans le REPL que j'ai réalisé qu'il s'agissait de caractères unicode.

2 votes

Votre tableau n'a aucun sens. Ligne 1 - vous appelez chaque fonction 1 fois pour "038"? Ou appelez-vous chaque fonction 3 fois - pour `"038", "", ""` et chaque fonction renvoie le même résultat pour l'ensemble de `"038", "", ""`?

5 votes

Les deux façons fonctionnent. Je vous recommande de les essayer vous-même.

117voto

wim Points 35274

Il s'agit surtout de classifications unicode. Voici quelques exemples pour montrer les disparités:

>>> 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

Le 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)

1 votes

Merci. Où puis-je trouver de la documentation explicite sur leur fonctionnement ? Je n'ai rien trouvé de détaillé dans la documentation officielle.

48voto

Christian Dean Points 14809

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

str.isdigit

Renvoie vrai si tous les caractères de la chaîne sont des chiffres et s'il y a au moins un caractère, faux sinon. Les chiffres incluent les caractères décimaux et les chiffres nécessitant 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 chiffres kharosthi. Formellement, un chiffre est un caractère ayant la propriété Numeric_Type=Chiffre ou Numeric_Type=Décimal.

str.isnumeric

Renvoie vrai 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, faux sinon. Les caractères numériques incluent les caractères numériques et tous les caractères ayant la propriété de valeur numérique Unicode, p. ex. U+2155, fraction vulgaire un cinquième. Formellement, les caractères numériques sont ceux ayant la propriété de valeur Numeric_Type=Chiffre, Numeric_Type=Décimal ou Numeric_Type=Numérique.

str.isdecimal

Renvoie vrai si tous les caractères de la chaîne sont des caractères décimaux et s'il y a au moins un caractère, faux sinon. Les caractères décimaux sont ceux qui peuvent être utilisés pour former des nombres en base 10, p. ex. U+0660, chiffre indicatif arabe zéro. Formellement, un caractère décimal est un caractère de la catégorie générale Unicode “Nd”.


Comme l'a dit @Wim, 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.

3 votes

Voici quelques-unes des parties les moins utiles et les plus trompeuses de l'API Python. Nous avons vraiment besoin d'un isfloat et les mal nommés isdecimal et isnumeric sont facilement confondus avec ceux-ci.

1 votes

Bonne réponse mais cela aurait légèrement aidé à la lecture si vous les aviez répertoriés dans un ordre logique : isdecimal - isdigit - isnumeric.

1voto

eashwar Points 1

Un nombre négatif a = "-10" serait faux pour ces trois-là

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

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

0 votes

Essayez-vous de dire que 'X'.isnumeric() renvoie True? Ce n'est pas le cas.

8 votes

''.isnumeric() est True, tandis que 'X'.isnumeric() est False. Ils semblent similaires aux yeux humains, mais sont en réalité des caractères différents.

-1voto

Douglas Points 59

Question connexe : lequel est équivalent à "\d" en expression régulière ?

"\d" : Pour les modèles Unicode (str) : Correspond à tout chiffre décimal Unicode (c'est-à-dire tout caractère de la catégorie de caractères Unicode [Nd]). Cela inclut [0-9], ainsi que de nombreux autres caractères de chiffres. Si le drapeau ASCII est utilisé, seul [0-9] est pris en compte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X