What Is the Most Pythonic Way to Check If an Object Is a Number

How can I check if my python object is a number?

Test if your variable is an instance of numbers.Number:

>>> import numbers
>>> import decimal
>>> [isinstance(x, numbers.Number) for x in (0, 0.0, 0j, decimal.Decimal(0))]
[True, True, True, True]

This uses ABCs and will work for all built-in number-like classes, and also for all third-party classes if they are worth their salt (registered as subclasses of the Number ABC).

However, in many cases you shouldn't worry about checking types manually - Python is duck typed and mixing somewhat compatible types usually works, yet it will barf an error message when some operation doesn't make sense (4 - "1"), so manually checking this is rarely really needed. It's just a bonus. You can add it when finishing a module to avoid pestering others with implementation details.

This works starting with Python 2.6. On older versions you're pretty much limited to checking for a few hardcoded types.

What is the most pythonic way to check if an object is a number?

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'{n!r:>14} {isinstance(n, Number)}')
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.

How to determine that a Python object is numeric?

The preferred approach is to use numbers.Number, which is

The root of the numeric hierarchy. If you just want to check if an
argument x is a number, without caring what kind, use isinstance(x,
Number
)

as shown below

In [1]: import numbers

In [2]: isinstance(1, numbers.Number)
Out[2]: True

In [3]: isinstance(1.0, numbers.Number)
Out[3]: True

In [4]: isinstance(1j, numbers.Number)
Out[4]: True

Also, type(o) in [int, long, float, complex] can be rewritten as

isinstance(o, (int, long, float, complex))

to make it more robust, as in able to detect subclasses of int, long, float and complex.

Check if a value is any number in Python

If you're willing to do add an import, this works:

import numbers

variable = 5
print(isinstance(variable, numbers.Number))

For the second question, do

x = {}
print(type(x) in [list, dict, tuple, set])

What is the best way to check if a variable is of numeric type in python

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

How to properly use python's isinstance() to check if a variable is a number?

In Python 2, you can use the types module:

>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True

Note the use of a tuple to test against multiple types.

Under the hood, IntType is just an alias for int, etc.:

>>> isinstance(var, (int, long, float, complex))
True

The complex type requires that your python was compiled with support for complex numbers; if you want to guard for this use a try/except block:

>>> try:
... NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
... except AttributeError:
... # No support for complex numbers compiled
... NumberTypes = (types.IntType, types.LongType, types.FloatType)
...

or if you just use the types directly:

>>> try:
... NumberTypes = (int, long, float, complex)
... except NameError:
... # No support for complex numbers compiled
... NumberTypes = (int, long, float)
...

In Python 3 types no longer has any standard type aliases, complex is always enabled and there is no longer a long vs int difference, so in Python 3 always use:

NumberTypes = (int, float, complex)

Last but not least, you can use the numbers.Numbers abstract base type (new in Python 2.6) to also support custom numeric types that don't derive directly from the above types:

>>> import numbers
>>> isinstance(var, numbers.Number)
True

This check also returns True for decimal.Decimal() and fractions.Fraction() objects.

This module does make the assumption that the complex type is enabled; you'll get an import error if it is not.

Checking whether a variable is an integer or not

If you need to do this, do

isinstance(<var>, int)

unless you are in Python 2.x in which case you want

isinstance(<var>, (int, long))

Do not use type. It is almost never the right answer in Python, since it blocks all the flexibility of polymorphism. For instance, if you subclass int, your new class should register as an int, which type will not do:

class Spam(int): pass
x = Spam(0)
type(x) == int # False
isinstance(x, int) # True

This adheres to Python's strong polymorphism: you should allow any object that behaves like an int, instead of mandating that it be one.

BUT

The classical Python mentality, though, is that it's easier to ask forgiveness than permission. In other words, don't check whether x is an integer; assume that it is and catch the exception results if it isn't:

try:
x += 1
except TypeError:
...

This mentality is slowly being overtaken by the use of abstract base classes, which let you register exactly what properties your object should have (adding? multiplying? doubling?) by making it inherit from a specially-constructed class. That would be the best solution, since it will permit exactly those objects with the necessary and sufficient attributes, but you will have to read the docs on how to use it.

What is the best way to check if a variable is a list?

These all express different things, so really it depends on exactly what you wish to achieve:

  • isinstance(x, list) check if the type of x is either list or has list as a parent class (lets ignore ABCs for simplicity etc);
  • type(x) is list checks if the type of x is precisely list;
  • type(x) == list checks for equality of types, which is not the same as being identical types as the metaclass could conceivably override __eq__

So in order they express the following:

  • isinstance(x, list): is x like a list
  • type(x) is list: is x precisely a list and not a sub class
  • type(x) == list: is x a list, or some other type using metaclass magic to masquerade as a list.

What is the pythonic way of checking if an object is a list?

In such situations, you normally need to check for ANY iterable, not just lists -- if you're accepting lists OR numbers, rejecting (e.g) a tuple would be weird. The one kind of iterable you might want to treat as a "scalar" is a string -- in Python 2.*, this means str or unicode. So, either:

def isNonStringIterable(x):
if isinstance(x, basestring):
return False
try: iter(x)
except: return False
else: return True

or, usually much handier:

def makeNonStringIterable(x):
if isinstance(x, basestring):
return (x,)
try: return iter(x)
except: return (x,)

where you just go for i in makeNonStringIterable(x): ...



Related Topics



Leave a reply



Submit