Jak sprawdzić w Pythonie, czy ciąg zawiera tylko liczby?


133

Jak sprawdzić, czy ciąg zawiera tylko liczby?

Dałem temu szansę. Chciałbym zobaczyć najprostszy sposób na osiągnięcie tego.

import string

def main():
    isbn = input("Enter your 10 digit ISBN number: ")
    if len(isbn) == 10 and string.digits == True:
        print ("Works")
    else:
        print("Error, 10 digit number was not inputted and/or letters were inputted.")
        main()

if __name__ == "__main__":
    main()
    input("Press enter to exit: ")

1
Twój kod będzie zawsze zwracany, Falseponieważ string.digits == Truezawsze ma wartość False.
Sukrit Kalra

1
Z wyjątkiem poniższych odpowiedzi, sposób "nie-Pythonowy" jest taki, że [x for x in isbn if x in '0123456789']; które możesz rozszerzyć, jeśli użytkownik umieści separatory w isbn - dodaj je do listy
cox

1
Zalecam użycie wyrażenia regularnego, jeśli czytasz numery ISBN. Numery ISBN mogą mieć 10 lub 13 cyfr i mieć dodatkowe ograniczenia. Tutaj znajduje się dobra lista poleceń regex do ich dopasowywania: regexlib.com/… Wiele z nich umożliwia również poprawne odczytywanie łączników ISBN, co ułatwia kopiowanie i wklejanie.
Kevin

1
@Kevin I chociaż 13-cyfrowe numery ISBN to w rzeczywistości tylko cyfry, 10-cyfrowe numery ISBN mogą mieć X jako ostatni znak.
TRiG

Odpowiedzi:


252

Będziesz chciał użyć tej isdigitmetody na swoim strobiekcie:

if len(isbn) == 10 and isbn.isdigit():

Z isdigitdokumentacji :

str.isdigit ()

Zwróć True, jeśli wszystkie znaki w ciągu są cyframi i jest co najmniej jeden znak, w przeciwnym razie False. Cyfry obejmują znaki dziesiętne i cyfry, które wymagają specjalnej obsługi, na przykład cyfry indeksu górnego zgodności. Dotyczy to cyfr, których nie można użyć do utworzenia liczb o podstawie 10, takich jak liczby Kharosthi. Formalnie cyfra to znak, który ma wartość właściwości Numeric_Type = Digit lub Numeric_Type = Decimal.


18
Warto zauważyć, że może to nie być czek, którego faktycznie potrzebujesz. To sprawdza, czy wszystkie znaki są podobne do cyfr , a nie, czy ciąg jest liczbą możliwą do przeanalizowania. Na przykład ciąg „⁰” (czyli zero w indeksie górnym w kodzie Unicode) przechodzi isdigit, ale wywołuje znak a, ValueErrorjeśli jest przekazywany do int().
danpalmer

42

Zastosowanie str.isdigit:

>>> "12345".isdigit()
True
>>> "12345a".isdigit()
False
>>>

Nie miałem pojęcia, że ​​metoda istnieje. Zawsze to robiłem try: assert str(int(foo)) == foo; except (AssertionError,ValueError): #handlei było to brzydkie jak grzech. Dzięki!
Adam Smith

10

Użyj funkcji string isdigit :

>>> s = '12345'
>>> s.isdigit()
True
>>> s = '1abc'
>>> s.isdigit()
False

3

Możesz też użyć wyrażenia regularnego,

import re

np .: -1) słowo = „3487954”

re.match('^[0-9]*$',word)

np .: -2) słowo = „3487,954”

re.match('^[0-9\.]*$',word)

np .: -3) słowo = „3487,954 328”

re.match('^[0-9\.\ ]*$',word)

Jak widać, wszystkie 3 np. Oznaczają, że w ciągu nie ma tylko żadnego. Możesz więc śledzić odpowiednie rozwiązania podane wraz z nimi.


1
re.match('^[0-9\.]*$',word)nie działa dla pływaków. if(bool(re.search(r'\d', word)))działa jednak dobrze.

3

Jak wskazano w tym komentarzu, jak sprawdzić w Pythonie, czy ciąg zawiera tylko liczby? isdigit()metoda nie jest całkowicie dokładne w tym przypadku zastosowania, ponieważ zwraca True dla niektórych znaków numerycznych, takich jak:

>>> "\u2070".isdigit() # unicode escaped 'superscript zero' 
True

Jeśli trzeba tego uniknąć, poniższa prosta funkcja sprawdza, czy wszystkie znaki w ciągu są cyframi od „0” do „9”:

import string

def contains_only_digits(s):
    # True for "", "0", "123"
    # False for "1.2", "1,2", "-1", "a", "a1"
    for ch in s:
        if not ch in string.digits:
            return False
    return True

Użyty w przykładzie z pytania:

if len(isbn) == 10 and contains_only_digits(isbn):
    print ("Works")

To drobiazg, ale funkcję można uprościć do all(ch in string.digits for ch in s).
AMC

2

Co z liczb zmiennoprzecinkowych , negatywy liczb itp .. Wszystkie przykłady zanim będzie źle.

Do tej pory dostałem coś takiego, ale myślę, że mogłoby być dużo lepiej:

'95.95'.replace('.','',1).isdigit()

zwróci prawdę tylko wtedy, gdy istnieje jeden lub nie ma znaku „.” w ciągu cyfr.

'9.5.9.5'.replace('.','',1).isdigit()

zwróci wartość false


Wszystkie powyższe przykłady będą błędne. Czy to nie dlatego, że pytanie dotyczy czegoś innego?
AMC

1

Możesz użyć bloku try catch tutaj:

s="1234"
try:
    num=int(s)
    print "S contains only digits"
except:
    print "S doesn't contain digits ONLY"

działa to tylko z liczbami całkowitymi, z liczbami zmiennoprzecinkowymi zawsze zawodzi, ponieważ zawiera (.)
Eddwin Paz

2
Ponadto zawsze złą praktyką jest nieokreślanie wyjątku, który chcesz obsłużyć. W tym przypadku powinno to być:except ValueError:
J0ANMM

Ale to nie jest poprawne, prawda? int("1_000")na przykład nie prowadzi do błędu.
AMC

1

Za każdym razem, gdy napotykam problem z czekiem, jest to, że czasami str może mieć wartość None, a jeśli str może mieć wartość None, użycie tylko str.isdigit () nie wystarczy, ponieważ pojawi się błąd

AttributeError: Obiekt „NoneType” nie ma atrybutu „isdigit”

a następnie musisz najpierw sprawdzić, czy str ma wartość None lub nie. Aby uniknąć rozgałęzienia typu multi-if, jasnym sposobem na to jest:

if str and str.isdigit():

Mam nadzieję, że to pomoże ludziom, którzy mają taki sam problem jak ja.


1

Są 2 metody, które mogę wymyślić, aby sprawdzić, czy ciąg ma wszystkie cyfry lub nie

Metoda 1 (użycie wbudowanej funkcji isdigit () w Pythonie): -

>>>st = '12345'
>>>st.isdigit()
True
>>>st = '1abcd'
>>>st.isdigit()
False

Metoda 2 (wykonywanie obsługi wyjątków na początku ciągu): -

st="1abcd"
try:
    number=int(st)
    print("String has all digits in it")
except:
    print("String does not have all digits in it")

Wynik powyższego kodu będzie:

String does not have all digits in it

Używanie gołego „oprócz” jest złą praktyką, zobacz na przykład Co jest złego w używaniu gołego „oprócz”? .
AMC

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.