Wednesday 27 January 2016

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?


Answer





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




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




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




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.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...