What is the most pythonic way to check if an object is a number?
Given an arbitrary python object, what’s the best way to determine whether it is a number? Here is is defined as acts like a number in certain circumstances . For example, say you are writing a vector class. If given another vector, you want to find the dot product. If given a scalar, you want to scale the whole vector. Checking if something is int , float , long , bool is annoying and doesn’t cover user-defined objects that might act like numbers. But, checking for __mul__ , for example, isn’t good enough because the vector class I just described would define __mul__ , but it wouldn’t be the kind of number I want.
16 Answers 16
Use Number from the numbers module to test isinstance(n, Number) (available since 2.6).
>>> from numbers import Number . from decimal import Decimal . from fractions import Fraction . for n in [2, 2.0, Decimal('2.0'), complex(2, 0), Fraction(2, 1), '2']: . print(f'14> ') 2 True 2.0 True Decimal('2.0') True (2+0j) True Fraction(2, 1) True '2' False
This is, of course, contrary to duck typing. If you are more concerned about how an object acts rather than what it is, perform your operations as if you have a number and use exceptions to tell you otherwise.
Doing the smart thing, rather than the duck thing, is preferred when you’re multiplying a vector by X. In this case you want to do different things based on what X is. (It might act as something that multiplies, but the result might be nonsensical.)
this answer gives would say True is a number.. which is probably not always what you want. For exlcuding booleans (think validation f.e.), I would say isinstance(value, Number) and type(value) != bool
The method in this answer will tell you that float(«-inf») is a number. Depending on the situation, that might not be appropriate.
You want to check if some object
acts like a number in certain circumstances
If you’re using Python 2.5 or older, the only real way is to check some of those «certain circumstances» and see.
In 2.6 or better, you can use isinstance with numbers.Number — an abstract base class (ABC) that exists exactly for this purpose (lots more ABCs exist in the collections module for various forms of collections/containers, again starting with 2.6; and, also only in those releases, you can easily add your own abstract base classes if you need to).
Bach to 2.5 and earlier, «can be added to 0 and is not iterable» could be a good definition in some cases. But, you really need to ask yourself, what it is that you’re asking that what you want to consider «a number» must definitely be able to do, and what it must absolutely be unable to do — and check.
This may also be needed in 2.6 or later, perhaps for the purpose of making your own registrations to add types you care about that haven’t already be registered onto numbers.Numbers — if you want to exclude some types that claim they’re numbers but you just can’t handle, that takes even more care, as ABCs have no unregister method [[for example you could make your own ABC WeirdNum and register there all such weird-for-you types, then first check for isinstance thereof to bail out before you proceed to checking for isinstance of the normal numbers.Number to continue successfully.
BTW, if and when you need to check if x can or cannot do something, you generally have to try something like:
try: 0 + x except TypeError: canadd=False else: canadd=True
The presence of __add__ per se tells you nothing useful, since e.g all sequences have it for the purpose of concatenation with other sequences. This check is equivalent to the definition «a number is something such that a sequence of such things is a valid single argument to the builtin function sum «, for example. Totally weird types (e.g. ones that raise the «wrong» exception when summed to 0, such as, say, a ZeroDivisionError or ValueError &c) will propagate exception, but that’s OK, let the user know ASAP that such crazy types are just not acceptable in good company;-); but, a «vector» that’s summable to a scalar (Python’s standard library doesn’t have one, but of course they’re popular as third party extensions) would also give the wrong result here, so (e.g.) this check should come after the «not allowed to be iterable» one (e.g., check that iter(x) raises TypeError , or for the presence of special method __iter__ — if you’re in 2.5 or earlier and thus need your own checks).
A brief glimpse at such complications may be sufficient to motivate you to rely instead on abstract base classes whenever feasible. ;-).
Python: Check if Variable is a Number
In this article, we’ll be going through a few examples of how to check if a variable is a number in Python.
Python is dynamically typed. There is no need to declare a variable type, while instantiating it — the interpreter infers the type at runtime:
variable = 4 another_variable = 'hello'
Additionally, a variable can be reassigned to a new type at any given time:
# Assign a numeric value variable = 4 # Reassign a string value variable = 'four'
This approach, while having advantages, also introduces us to a few issues. Namely, when we receive a variable, we typically don’t know of which type it is. If we’re expecting a Number, but receive variable , we’ll want to check if it’s a number before working with it.
Using the type() Function
The type() function in Python returns the type of the argument we pass to it, so it’s a handy function for this purpose:
myNumber = 1 print(type(myNumber)) myFloat = 1.0 print(type(myFloat)) myString = 's' print(type(myString))
Thus, a way to check for the type is:
myVariable = input('Enter a number') if type(myVariable) == int or type(myVariable) == float: # Do something else: print('The variable is not a number')
Here, we check if the variable type, entered by the user is an int or a float , proceeding with the program if it is. Otherwise, we notify the user that they’ve entered a non-Number variable. Please keep in mind that if you’re comparing to multiple types, such as int or float , you have to use the type() function both times.
If we just said if type(var) == int or float , which is seemingly fine, an issue would arise:
myVariable = 'A string' if type(myVariable) == int or float: print('The variable a number') else: print('The variable is not a number')
This, regardless of the input, returns:
This is because Python checks for truth values of the statements. Variables in Python can be evaluated as True except for False , None , 0 and empty containers like [] , <> , set() , () , » or «» .
Hence when we write or float in our if condition, it is equivalent to writing or True which will always evaluate to True .
numbers.Number
A good way to check if a variable is a number is the numbers module. You can check if the variable is an instance the Number class, with the isinstance() function:
import numbers variable = 5 print(isinstance(5, numbers.Number))
Free eBook: Git Essentials
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Note: This approach can behave unexpectedly with numeric types outside of core Python. Certain frameworks might have non- Number numeric implementation, in which case this approach will falsely return False .
Using a try-except block
Another method to check if a variable is a number is using a try-except block. In the try block, we cast the given variable to an int or float . Successful execution of the try block means that a variable is a number i.e. either int or float :
myVariable = 1 try: tmp = int(myVariable) print('The variable a number') except: print('The variable is not a number')
This works for both int and float because you can cast an int to float and a float to an int .
If you specifically only want to check if a variable is one of these, you should use the type() function.
Conclusion
Python is a dynamically typed language, which means that we might receive a data type different than the one we’re expecting.
In cases where we’d want to enforce data types, it’s worth checking if a variable is of the desired type. In this article, we’ve covered three ways to check if a variable is a Number in Python.
What is the best way to check if a variable is of numeric type in python
I understand that I could use type() and isinstance() to check if a variable is of a certain type or belongs to certain class. I was wondering if there is a quick way to check if a variable is of a ‘numeric’ type, similar to isnumeric in MATLAB. It should return True if the variable is int, long, float, double, arrays of ints or floats etc. Any suggestions are greatly appreciated. Thank you.
Arrays are not going to be testable this way — what if the fisrt vlue is numeric and the second is a string? If you want to check them all, iterate (or use one of the many helper methods that do the same)
2 Answers 2
The easiest way to check if an object is a number is to do arithmethic operations (such as add 0) and see if we can get away with it:
def isnumeric(obj): try: obj + 0 return True except TypeError: return False print isnumeric([1,2,3]) # False print isnumeric(2.5) # True print isnumeric('25') # False
@Srikanth, sorry, I’ve just deleted my comment suggesting this would be a false positive for numpy arrays. Indeed, I hadn’t realised you were including numpy arrays as «numbers».
I stand by my comment: I don’t consider an array a number. My solution therefore is not correct. It just happens to produce the right answer for the wrong reason.
I agree, but your answer actually answers the question once we read into the details of the question, so that makes is a good answer.
Check to see if each item can be converted to a float:
def mat_isnumeric(input): if type(input) is list: for item in input: if not is_a_number(item): return False return True else: return is_a_number(input) def is_a_number(input): try: float(input) return True except ValueError: return False
Running the following script:
if __name__ == "__main__": print(mat_isnumeric(321354651)) print(mat_isnumeric(3213543.35135)) print(mat_isnumeric(['324234324', '2342342', '2343242', '23432.324234'])) print(mat_isnumeric('asdfasdfsadf')) print(mat_isnumeric(['234234', '32432.324324', 'asdfsadfad']))
True True True False False