173

How do you check whether a string contains only numbers?

I've given it a go here. I'd like to see the simplest way to accomplish this.

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: ")
TRiG
  • 10,148
  • 7
  • 57
  • 107
Coder77
  • 2,203
  • 5
  • 20
  • 28
  • 1
    Your code will always return `False` since `string.digits == True` always evaluates to `False`. – Sukrit Kalra Jan 27 '14 at 18:23
  • 1
    Except the answers below, a "Non Pythonic" way is if [x for x in isbn if x in '0123456789']; that you can extend if the user put separators in isbn - add them to list – cox Jan 27 '14 at 18:24
  • 1
    I recommend using regex if you are reading ISBN numbers. ISBNs can be either 10 or 13 digits long, and have additional restrictions. There is a good list of regex commands for matching them here: http://regexlib.com/Search.aspx?k=isbn&AspxAutoDetectCookieSupport=1 Many of these will also let you correctly read the ISBN hyphens, which will make it easier for people to copy and paste. – Kevin Jan 27 '14 at 18:25
  • 1
    @Kevin And, while 13-digit ISBNs are indeed digits only, 10-digit ISBNs can have X as the final character. – TRiG Mar 24 '17 at 11:34

12 Answers12

297

You'll want to use the isdigit method on your str object:

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

From the isdigit documentation:

str.isdigit()

Return True if all characters in the string are digits and there is at least one character, False otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the property value Numeric_Type=Digit or Numeric_Type=Decimal.

Community
  • 1
  • 1
mhlester
  • 22,781
  • 10
  • 52
  • 75
  • 30
    Worth noting that this may not be the check you actually want. This checks that all characters are _digit-like_, not that the string is a parseable number. For example, the string " ⁰" (that is a unicode superscript zero), does pass `isdigit`, but raises a `ValueError` if passed to `int()`. – danpalmer Mar 04 '19 at 12:04
  • Thanks for the very relevant comment @danpalmer. I wanted to make sure my string is an integer (positive or negative) only, so I needed to do something more explicit as in [here](https://stackoverflow.com/questions/35131490/how-to-i-check-that-a-string-contains-only-digits-and-in-python) – GreenEye Nov 23 '20 at 16:57
54

Use str.isdigit:

>>> "12345".isdigit()
True
>>> "12345a".isdigit()
False
>>>
  • 1
    I had no idea that method existed. I've always done `try: assert str(int(foo)) == foo; except (AssertionError,ValueError): #handle` and it felt ugly as sin. Thanks! – Adam Smith Jan 27 '14 at 18:23
  • 1
    Keep in mind `"²".isdigit()` (the 2 superscript) returns True but `int("²")` errors. – Discrete Games May 17 '21 at 22:45
17

Use string isdigit function:

>>> s = '12345'
>>> s.isdigit()
True
>>> s = '1abc'
>>> s.isdigit()
False
AMC
  • 2,642
  • 7
  • 13
  • 35
ndpu
  • 22,225
  • 6
  • 54
  • 69
9

You can also use the regex,

import re

eg:-1) word = "3487954"

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

eg:-2) word = "3487.954"

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

eg:-3) word = "3487.954 328"

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

As you can see all 3 eg means that there is only no in your string. So you can follow the respective solutions given with them.

Devendra Bhat
  • 1,149
  • 2
  • 14
  • 19
  • 1
    `re.match('^[0-9\.]*$',word)` fails for floats. `if(bool(re.search(r'\d', word)))` works fine though. –  Feb 13 '19 at 18:35
4

As pointed out in this comment How do you check in python whether a string contains only numbers? the isdigit() method is not totally accurate for this use case, because it returns True for some digit-like characters:

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

If this needs to be avoided, the following simple function checks, if all characters in a string are a digit between "0" and "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

Used in the example from the question:

if len(isbn) == 10 and contains_only_digits(isbn):
    print ("Works")
mit
  • 11,083
  • 11
  • 50
  • 74
  • 1
    It's a small thing, but the function can be simplified to `all(ch in string.digits for ch in s)`. – AMC Jun 02 '20 at 23:09
3

What about of float numbers, negatives numbers, etc.. All the examples before will be wrong.

Until now I got something like this, but I think it could be a lot better:

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

will return true only if there is one or no '.' in the string of digits.

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

will return false

Joe9008
  • 645
  • 7
  • 14
  • _All the examples before will be wrong._ Isn't that because the question is about something else? – AMC Jun 02 '20 at 23:21
2

As every time I encounter an issue with the check is because the str can be None sometimes, and if the str can be None, only use str.isdigit() is not enough as you will get an error

AttributeError: 'NoneType' object has no attribute 'isdigit'

and then you need to first validate the str is None or not. To avoid a multi-if branch, a clear way to do this is:

if str and str.isdigit():

Hope this helps for people have the same issue like me.

zhihong
  • 1,808
  • 2
  • 24
  • 34
  • Actually, isdigit ensures that str is truthy, since isdigit returns False if it does not have at least one character. So you could remove the str if you wanted to go with isdigit. – Justin Furuness Jun 22 '21 at 07:16
  • You shouldn't use `str` as a variable name as it overrides the builtin of the same name – jtlz2 Mar 10 '23 at 22:28
1

You can use try catch block here:

s="1234"
try:
    num=int(s)
    print "S contains only digits"
except:
    print "S doesn't contain digits ONLY"
cold_coder
  • 584
  • 4
  • 8
  • 24
  • this only works with integers, with float numbers will always fail since it contains a (.) – Eddwin Paz Jun 24 '16 at 09:17
  • 3
    In addition, it is always a bad practice not to specify which exception you want to handle. In this case it should be: `except ValueError:` – J0ANMM Jan 24 '17 at 09:11
  • This isn't correct though, no? `int("1_000")` doesn't lead to an error, for example. – AMC Jun 02 '20 at 23:08
1

There are 2 methods that I can think of to check whether a string has all digits of not

Method 1(Using the built-in isdigit() function in python):-

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

Method 2(Performing Exception Handling on top of the string):-

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

The output of the above code will be:

String does not have all digits in it
Rahul
  • 325
  • 5
  • 11
  • 1
    Using a bare except like that is bad practice, see for example [What is wrong with using a bare 'except'?](https://stackoverflow.com/questions/54948548/what-is-wrong-with-using-a-bare-except). – AMC Jun 02 '20 at 23:11
1

you can use str.isdigit() method or str.isnumeric() method

Faith
  • 27
  • 6
  • 3
    Isn't this the same solution as the top 2 answers (https://stackoverflow.com/a/21388567/11301900, https://stackoverflow.com/a/21388552/11301900) ? – AMC Jun 02 '20 at 23:15
0

You can use this one too:

re.match(r'^[\d]*$' , YourString) 
0x27752357
  • 34
  • 4
  • Why is there an `f` at the start? If this is an f-string, there is no var to replace. Or do you mean `r'...'` for a raw string? It's actually better not to make this an f-string. – Gino Mempin Jul 16 '22 at 11:21
  • Right, because you don't need this to be an f-string. You don't need the `f` at the start. – Gino Mempin Jul 18 '22 at 00:41
0

Solution:

def main():
    isbn = input("Enter your 10 digit ISBN number: ")
    try:
        int(isbn)
        is_digit = True
    except ValueError:
        is_digit = False
    if len(isbn) == 10 and is_digit:
        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: ")
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 25 '22 at 08:53