# [python] Detect whether a Python string is a number or a letter

How can I detect either numbers or letters in a string? I am aware you use the ASCII codes, but what functions take advantage of them?

This question is related to `python` `string` `ascii`

## Check if string is positive digit (integer) and alphabet

You may use `str.isdigit()` and `str.isalpha()` to check whether given string is positive integer and alphabet respectively.

Sample Results:

``````# For alphabet
>>> 'A'.isdigit()
False
>>> 'A'.isalpha()
True

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False
``````

## Check for strings as positive/negative - integer/float

`str.isdigit()` returns `False` if the string is a negative number or a float number. For example:

``````# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False
``````

If you want to also check for the negative integers and `float`, then you may write a custom function to check for it as:

``````def is_number(n):
try:
float(n)   # Type-casting the string to `float`.
# If string is not a valid `float`,
# it'll raise `ValueError` exception
except ValueError:
return False
return True
``````

Sample Run:

``````>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True

>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False
``````

## Discard "NaN" (not a number) strings while checking for number

The above functions will return `True` for the "NAN" (Not a number) string because for Python it is valid float representing it is not a number. For example:

``````>>> is_number('NaN')
True
``````

In order to check whether the number is "NaN", you may use `math.isnan()` as:

``````>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True
``````

Or if you don't want to import additional library to check this, then you may simply check it via comparing it with itself using `==`. Python returns `False` when `nan` float is compared with itself. For example:

``````# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False
``````

Hence, above function `is_number` can be updated to return `False` for `"NaN"` as:

``````def is_number(n):
is_number = True
try:
num = float(n)
# check for "nan" floats
is_number = num == num   # or use `math.isnan(num)`
except ValueError:
is_number = False
return is_number
``````

Sample Run:

``````>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False
``````

## Allow Complex Number like "1+2j" to be treated as valid number

The above function will still return you `False` for the complex numbers. If you want your `is_number` function to treat complex numbers as valid number, then you need to type cast your passed string to `complex()` instead of `float()`. Then your `is_number` function will look like:

``````def is_number(n):
is_number = True
try:
#      v type-casting the number here as `complex`, instead of `float`
num = complex(n)
is_number = num == num
except ValueError:
is_number = False
return is_number
``````

Sample Run:

``````>>> is_number('1+2j')    # Valid
True                     #      : complex number

>>> is_number('1+ 2j')   # Invalid
False                    #      : string with space in complex number represetantion
#        is treated as invalid complex number

>>> is_number('123')     # Valid
True                     #      : positive integer

>>> is_number('-123')    # Valid
True                     #      : negative integer

>>> is_number('abc')     # Invalid
False                    #      : some random string, not a valid number

>>> is_number('nan')     # Invalid
False                    #      : not a number "nan" string
``````

PS: Each operation for each check depending on the type of number comes with additional overhead. Choose the version of `is_number` function which fits your requirement.

For a string of length 1 you can simply perform `isdigit()` or `isalpha()`

If your string length is greater than 1, you can make a function something like..

``````def isinteger(a):
try:
int(a)
return True
except ValueError:
return False
``````