183

How do I check if a user's string input is a number (e.g., -1, 0, 1, etc.)?

user_input = input("Enter something:")

if type(user_input) == int:
    print("Is a number")
else:
    print("Not a number")

The above won't work since input always returns a string.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Trufa
  • 39,971
  • 43
  • 126
  • 190

30 Answers30

303

Simply try converting it to an int and then bailing out if it doesn't work.

try:
    val = int(userInput)
except ValueError:
    print("That's not an int!")

See Handling Exceptions in the official tutorial.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Daniel DiPaolo
  • 55,313
  • 14
  • 116
  • 115
111

Apparently this will not work for negative values, but it will for positive numbers.

Use isdigit()

if userinput.isdigit():
    #do stuff
Chandrahas Aroori
  • 955
  • 2
  • 14
  • 27
jmichalicek
  • 2,398
  • 1
  • 17
  • 7
  • 59
    "-1".isdigit() == False – BatchyX Mar 24 '11 at 19:55
  • 1
    I don't believe so, Llopis. I kind of jumped the gun answering questions before I knew enough back when I gave this answer. I would do the same as Daniel DiPaolo's answer for the int, but use float() instead of int(). – jmichalicek Jan 08 '14 at 18:50
  • 1
    Negative numbers and floats return false because '-' and '.' are not digits. The isdigit() function checks if every character in the string is between '0' and '9'. – Carl H Apr 14 '15 at 09:58
  • 2
    Use `isdecimal` not `isdigit` because `isdigit` is an unsafe test that recognises characters like unicode power-of-2, ² , as a digit that can not be converted to integers. – Dave Rove Jul 16 '20 at 11:45
58

The method isnumeric() will do the job:

>>>a = '123'
>>>a.isnumeric()
True

But remember:

>>>a = '-1'
>>>a.isnumeric()
False

isnumeric() returns True if all characters in the string are numeric characters, and there is at least one character.

So negative numbers are not accepted.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Andrés Fernández
  • 3,045
  • 2
  • 19
  • 21
  • 1
    Worth noting that in Python 2.7 this only works for unicode strings. A non-unicode string (`"123456".isnumeric()`) yields `AttributeError: 'str' object has no attribute 'isnumeric'`, while `U"12345".numeric()` = `True` – perlyking Feb 14 '17 at 09:21
  • 2
    Also, there are some edge cases where this doesn't work. Take `a = '\U0001f10a'`. `a.isnumeric()` is True, but `int(a)` raises a ValueError. – Artyer Jul 17 '17 at 22:14
  • 10
    `'3.3'.isnumeric()` is `False` – Deqing Jan 23 '18 at 00:08
26

For Python 3 the following will work.

userInput = 0
while True:
  try:
     userInput = int(input("Enter something: "))       
  except ValueError:
     print("Not an integer!")
     continue
  else:
     print("Yes an integer!")
     break 
RazorX
  • 269
  • 3
  • 3
12

EDITED: You could also use this below code to find out if its a number or also a negative

import re
num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$")
isnumber = re.match(num_format,givennumber)
if isnumber:
    print "given string is number"

you could also change your format to your specific requirement. I am seeing this post a little too late.but hope this helps other persons who are looking for answers :) . let me know if anythings wrong in the given code.

karthik27
  • 484
  • 1
  • 4
  • 12
  • This will check if there is a numeric (float, int, etc) within the string. However, if there is more than just the numeric, it will still return a result. For example: "1.2 Gbps" will return a false positive. This may or may not be useful to some people. – Brian Bruggeman May 28 '15 at 19:35
  • 1
    Also note: for anyone now looking, my original comment is no longer valid. :P Thanks for the update @karthik27! – Brian Bruggeman Aug 24 '15 at 14:30
9

If you specifically need an int or float, you could try "is not int" or "is not float":

user_input = ''
while user_input is not int:
    try:
        user_input = int(input('Enter a number: '))
        break
    except ValueError:
        print('Please enter a valid number: ')

print('You entered {}'.format(user_input))

If you only need to work with ints, then the most elegant solution I've seen is the ".isdigit()" method:

a = ''
while a.isdigit() == False:
    a = input('Enter a number: ')

print('You entered {}'.format(a))
Leonardo
  • 791
  • 1
  • 5
  • 21
Woody
  • 91
  • 1
  • 3
6

Works fine for check if an input is a positive Integer AND in a specific range

def checkIntValue():
    '''Works fine for check if an **input** is
   a positive Integer AND in a specific range'''
    maxValue = 20
    while True:
        try:
            intTarget = int(input('Your number ?'))
        except ValueError:
            continue
        else:
            if intTarget < 1 or intTarget > maxValue:
                continue
            else:
                return (intTarget)
5

I would recommend this, @karthik27, for negative numbers

import re
num_format = re.compile(r'^\-?[1-9][0-9]*\.?[0-9]*')

Then do whatever you want with that regular expression, match(), findall() etc

rachit_verma
  • 301
  • 1
  • 3
  • 8
5

The most elegant solutions would be the already proposed,

a = 123
bool_a = a.isnumeric()

Unfortunately, it doesn't work neither for negative integers nor for general float values of a. If your point is to check if 'a' is a generic number beyond integers, I'd suggest the following one, which works for every kind of float and integer :). Here is the test:

def isanumber(a):

    try:
        float(repr(a))
        bool_a = True
    except:
        bool_a = False

    return bool_a


a = 1 # Integer
isanumber(a)
>>> True

a = -2.5982347892 # General float
isanumber(a)
>>> True

a = '1' # Actually a string
isanumber(a)
>>> False
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
5

natural: [0, 1, 2 ... ∞]

Python 2

it_is = unicode(user_input).isnumeric()

Python 3

it_is = str(user_input).isnumeric()

integer: [-∞, .., -2, -1, 0, 1, 2, ∞]

try:
    int(user_input)
    it_is = True
except ValueError:
    it_is = False
 

float: [-∞, .., -2, -1.0...1, -1, -0.0...1, 0, 0.0...1, ..., 1, 1.0...1, ..., ∞]

try:
    float(user_input)
    it_is = True
except ValueError:
    it_is = False
Luis Sieira
  • 29,926
  • 3
  • 31
  • 53
4

This solution will accept only integers and nothing but integers.

def is_number(s):
    while s.isdigit() == False:
        s = raw_input("Enter only numbers: ")
    return int(s)


# Your program starts here    
user_input = is_number(raw_input("Enter a number: "))
Salam
  • 1,126
  • 14
  • 20
3

This works with any number, including a fraction:

import fractions

def isnumber(s):
   try:
     float(s)
     return True
   except ValueError:
     try: 
       Fraction(s)
       return True
     except ValueError: 
       return False
Antoni Gual Via
  • 714
  • 1
  • 6
  • 14
3

You can use the isdigit() method for strings. In this case, as you said the input is always a string:

    user_input = input("Enter something:")
    if user_input.isdigit():
        print("Is a number")
    else:
        print("Not a number")
Raj Shah
  • 766
  • 7
  • 15
2

Why not divide the input by a number? This way works with everything. Negatives, floats, and negative floats. Also Blank spaces and zero.

numList = [499, -486, 0.1255468, -0.21554, 'a', "this", "long string here", "455 street area", 0, ""]

for item in numList:

    try:
        print (item / 2) #You can divide by any number really, except zero
    except:
        print "Not A Number: " + item

Result:

249
-243
0.0627734
-0.10777
Not A Number: a
Not A Number: this
Not A Number: long string here
Not A Number: 455 street area
0
Not A Number: 
SPYBUG96
  • 1,089
  • 5
  • 20
  • 38
  • 4
    This only works because your numbers here are numeric types. An input of "8" (type str) would be "Not A Number." – fwip Sep 22 '19 at 20:52
1

I know this is pretty late but its to help anyone else that had to spend 6 hours trying to figure this out. (thats what I did):

This works flawlessly: (checks if any letter is in the input/checks if input is either integer or float)

a=(raw_input("Amount:"))

try:
    int(a)
except ValueError:
    try:
        float(a)
    except ValueError:
        print "This is not a number"
        a=0


if a==0:
    a=0
else:
    print a
    #Do stuff
1

Here is a simple function that checks input for INT and RANGE. Here, returns 'True' if input is integer between 1-100, 'False' otherwise

def validate(userInput):

    try:
        val = int(userInput)
        if val > 0 and val < 101:
            valid = True
        else:
            valid = False

    except Exception:
        valid = False

    return valid
Jesse Downing
  • 355
  • 4
  • 14
  • 1
    Welcome to Stack Overflow! This is an old question, and the accepted answer seems to be pretty good. Are you sure that you have something new to add? – Dietrich Epp Nov 11 '15 at 21:57
  • 1
    I thought it was a slight improvement: no less efficient while avoiding the nested if-else. I'm new here, if the answer hurts the community no hard feels if it's removed. – Jesse Downing Nov 11 '15 at 22:31
1

If you wanted to evaluate floats, and you wanted to accept NaNs as input but not other strings like 'abc', you could do the following:

def isnumber(x):
    import numpy
    try:
        return type(numpy.float(x)) == float
    except ValueError:
        return False
ryanjdillon
  • 17,658
  • 9
  • 85
  • 110
1

I've been using a different approach I thought I'd share. Start with creating a valid range:

valid = [str(i) for i in range(-10,11)] #  ["-10","-9...."10"] 

Now ask for a number and if not in list continue asking:

p = input("Enter a number: ")

while p not in valid:
    p = input("Not valid. Try to enter a number again: ")

Lastly convert to int (which will work because list only contains integers as strings:

p = int(p)
Anton vBR
  • 18,287
  • 5
  • 40
  • 46
0

I also ran into problems this morning with users being able to enter non-integer responses to my specific request for an integer.

This was the solution that ended up working well for me to force an answer I wanted:

player_number = 0
while player_number != 1 and player_number !=2:
    player_number = raw_input("Are you Player 1 or 2? ")
    try:
        player_number = int(player_number)
    except ValueError:
        print "Please enter '1' or '2'..."

I would get exceptions before even reaching the try: statement when I used

player_number = int(raw_input("Are you Player 1 or 2? ") 

and the user entered "J" or any other non-integer character. It worked out best to take it as raw input, check to see if that raw input could be converted to an integer, and then convert it afterward.

Luis Sieira
  • 29,926
  • 3
  • 31
  • 53
0
while True:
    b1=input('Type a number:')
    try:
        a1=int(b1)
    except ValueError:
        print ('"%(a1)s" is not a number. Try again.' %{'a1':b1})       
    else:
        print ('You typed "{}".'.format(a1))
        break

This makes a loop to check whether input is an integer or not, result would look like below:

>>> %Run 1.1.py
Type a number:d
"d" is not a number. Try again.
Type a number:
>>> %Run 1.1.py
Type a number:4
You typed 4.
>>> 
0

Try this! It worked for me even if I input negative numbers.

def length(s):
    return len(s)

s = input("Enter the string: ")
try:
    if (type(int(s))) == int:
        print("You input an integer")

except ValueError:
    print("it is a string with length " + str(length(s)))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

This will work:

print(user_input.isnumeric())

This checks if the string has only numbers in it and has at least a length of 1. However, if you try isnumeric with a string with a negative number in it, isnumeric will return False.

Now this is a solution that works for both negative and positive numbers

try:
    user_input = int(user_input)
except ValueError:
    process_non_numeric_user_input()  # user_input is not a numeric string!
else:
    process_user_input()
Alan Bagel
  • 818
  • 5
  • 24
0

I think not doing a simple thing in one line is not Pythonic.

A version without try..except, using a regex match:

Code:

import re

if re.match('[-+]?\d+$', the_str):
  # Is integer

Test:

>>> import re
>>> def test(s): return bool(re.match('[-+]?\d+$', s))

>>> test('0')
True
>>> test('1')
True
>>> test('-1')
True

>>> test('-0')
True
>>> test('+0')
True
>>> test('+1')
True


>>> test('-1-1')
False
>>> test('+1+1')
False
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yurenchen
  • 1,897
  • 19
  • 17
0

Looks like there's so far only two answers that handle negatives and decimals (the try... except answer and the regex one?). Found a third answer somewhere a while back somewhere (tried searching for it, but no success) that uses explicit direct checking of each character rather than a full regex.

Looks like it is still quite a lot slower than the try/exceptions method, but if you don't want to mess with those, some use cases may be better compared to regex when doing heavy usage, particularly if some numbers are short/non-negative:

>>> from timeit import timeit

On Python 3.10 on Windows shows representative results for me:

Explicitly check each character:

>>> print(timeit('text="1234"; z=text[0]; (z.isdigit() or z == "-" or z == ".") and all(character.isdigit() or character == "." for character in text[1:])'))
0.5673831000458449
>>> print(timeit('text="-4089175.25"; z=text[0]; (z.isdigit() or z == "-" or z == ".") and all(character.isdigit() or character == "." for character in text[1:])'))
1.0832774000009522
>>> print(timeit('text="-97271851234.28975232364"; z=text[0]; (z.isdigit() or z == "-" or z == ".") and all(character.isdigit() or character == "." for character in text[1:])'))
1.9836419000057504

A lot slower than the try/except:

>>> def exception_try(string):
...   try:
...     return type(float(string)) == int
...   except:
...     return false

>>> print(timeit('text="1234"; exception_try(text)', "from __main__ import exception_try"))
0.22721579996868968
>>> print(timeit('text="-4089175.25"; exception_try(text)', "from __main__ import exception_try"))
0.2409859000472352
>>> print(timeit('text="-97271851234.28975232364"; exception_try(text)', "from __main__ import exception_try"))
0.45190039998851717

But a fair bit quicker than regex, unless you have an extremely long string?

>>> print(timeit('import re'))
0.08660140004940331

(In case you're using it already)... and then:

>>> print(timeit('text="1234"; import re; num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$"); re.match(num_format,text)'))
1.3882658999646083
>>> print(timeit('text="-4089175.25"; import re; num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$"); re.match(num_format,text)'))
1.4007637000177056
>>> print(timeit('text="-97271851234.28975232364"; import re; num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$"); re.match(num_format,text)'))
1.4191589000402018

None are close to the simplest isdecimal, but that of course won't catch the negatives...

>>> print(timeit('text="1234"; text.isdecimal()'))
0.04747540003154427

Always good to have options depending on needs?

JeopardyTempest
  • 136
  • 1
  • 2
  • 10
0

I have found that some Python libraries use assertions to make sure that the value supplied by the programmer-user is a number.

Sometimes it's good to see an example 'from the wild'. Using assert/isinstance:

def check_port(port):
    assert isinstance(port, int), 'PORT is not a number'
    assert port >= 0, 'PORT < 0 ({0})'.format(port)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tonysepia
  • 3,340
  • 3
  • 27
  • 45
-1

Here is the simplest solution:

a= input("Choose the option\n")

if(int(a)):
    print (a);
else:
    print("Try Again")
Akshay Sahai
  • 2,121
  • 1
  • 17
  • 20
  • 1
    `SyntaxError: 'return' outside function`. Also, `a is int` will never evaluate to `True`. – Nelewout Jan 06 '16 at 20:48
  • thanks @N.Wouda for your help , i have made the changes,check this – Akshay Sahai Jan 06 '16 at 22:31
  • 1
    Are you sure that your answer is actually contributing something new to this question? – Nelewout Jan 06 '16 at 22:39
  • @N.Wouda actually I'm in a learning stage and trying to help others, so they don't get stuck in such basic problems. – Akshay Sahai Jan 06 '16 at 22:42
  • 1
    That is quite commendable, don't get me wrong. But this particular question seems like it was already well-covered by the other answers, so it might be more productive to answer questions that do not yet have good anwers! – Nelewout Jan 06 '16 at 22:51
  • 2
    If 'a' is a string, int(a) throws an exception and the 'else' branch never gets called. Tested in python 2 & 3. – nevelis Sep 13 '16 at 20:26
-1

You can type:

user_input = input("Enter something: ")

if type(user_input) == int:
    print(user_input, "Is a number")
else:
    print("Not a number")
  
try:
    val = int(user_input)
except ValueError:
    print("That's not an int!")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-1

Checking for Decimal type:

import decimal
isinstance(x, decimal.Decimal)
AidinZadeh
  • 724
  • 1
  • 8
  • 15
-2

This is based on inspiration from an answer. I defined a function as below. It looks like it’s working fine.

def isanumber(inp):
    try:
        val = int(inp)
        return True
    except ValueError:
        try:
            val = float(inp)
            return True
        except ValueError:
            return False
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-4
a=10

isinstance(a,int)  #True

b='abc'

isinstance(b,int)  #False
ryanjdillon
  • 17,658
  • 9
  • 85
  • 110
sachkh
  • 11