What is the best (idiomatic) way to check the type of a Python variable?


Question

I need to know if a variable in Python is a string or a dict. Is there anything wrong with the following code?

if type(x) == type(str()):
    do_something_with_a_string(x)
elif type(x) == type(dict()):
    do_somethting_with_a_dict(x)
else:
    raise ValueError

Update: I accepted avisser's answer (though I will change my mind if someone explains why isinstance is preferred over type(x) is).

But thanks to nakedfanatic for reminding me that it's often cleaner to use a dict (as a case statement) than an if/elif/else series.

Let me elaborate on my use case. If a variable is a string, I need to put it in a list. If it's a dict, I need a list of the unique values. Here's what I came up with:

def value_list(x):
    cases = {str: lambda t: [t],
             dict: lambda t: list(set(t.values()))}
    try:
        return cases[type(x)](x)
    except KeyError:
        return None

If isinstance is preferred, how would you write this value_list() function?

1
291
7/2/2015 12:00:24 PM

Accepted Answer

What happens if somebody passes a unicode string to your function? Or a class derived from dict? Or a class implementing a dict-like interface? Following code covers first two cases. If you are using Python 2.6 you might want to use collections.Mapping instead of dict as per the ABC PEP.

def value_list(x):
    if isinstance(x, dict):
        return list(set(x.values()))
    elif isinstance(x, basestring):
        return [x]
    else:
        return None
318
8/11/2018 9:31:06 PM

type(dict()) says "make a new dict, and then find out what its type is". It's quicker to say just "dict". But if you want to just check type, a more idiomatic way is isinstance(x, dict).

Note, that isinstance also includes subclasses (thanks Dustin):

class D(dict):
    pass

d = D()
print("type(d) is dict", type(d) is dict)  # -> False
print("isinstance (d, dict)", isinstance(d, dict))  # -> True

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon