How to Check If an Object Is a List or Tuple (But Not String)

How to check if an object is a list or tuple (but not string)?

In python 2 only (not python 3):

assert not isinstance(lst, basestring)

Is actually what you want, otherwise you'll miss out on a lot of things which act like lists, but aren't subclasses of list or tuple.

Check if input is a list/tuple of strings or a single string

You can check if a variable is a string or unicode string with

  • Python 3:
    isinstance(some_object, str)
  • Python 2:
    isinstance(some_object, basestring)

This will return True for both strings and unicode strings

As you are using python 2.5, you could do something like this:

if isinstance(some_object, basestring):
...
elif all(isinstance(item, basestring) for item in some_object): # check iterable for stringness of all items. Will raise TypeError if some_object is not iterable
...
else:
raise TypeError # or something along that line

Stringness is probably not a word, but I hope you get the idea

Test if a variable is a list or tuple

Go ahead and use isinstance if you need it. It is somewhat evil, as it excludes custom sequences, iterators, and other things that you might actually need. However, sometimes you need to behave differently if someone, for instance, passes a string. My preference there would be to explicitly check for str or unicode like so:

import types
isinstance(var, types.StringTypes)

N.B. Don't mistake types.StringType for types.StringTypes. The latter incorporates str and unicode objects.

The types module is considered by many to be obsolete in favor of just checking directly against the object's type, so if you'd rather not use the above, you can alternatively check explicitly against str and unicode, like this:

isinstance(var, (str, unicode)):

Edit:

Better still is:

isinstance(var, basestring)

End edit

After either of these, you can fall back to behaving as if you're getting a normal sequence, letting non-sequences raise appropriate exceptions.

See the thing that's "evil" about type checking is not that you might want to behave differently for a certain type of object, it's that you artificially restrict your function from doing the right thing with unexpected object types that would otherwise do the right thing. If you have a final fallback that is not type-checked, you remove this restriction. It should be noted that too much type checking is a code smell that indicates that you might want to do some refactoring, but that doesn't necessarily mean you should avoid it from the getgo.

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.

Elegant way to check if a list contains int, str, tuple and sub-list

You can use a tuple of different types with isinstance:

>>> isinstance('a', (str, list, tuple, int))
True

Combine with any

>>> data = [1, 'a', (2, 4, 6)]
>>> any(isinstance(x, (str, list, tuple, int)) for x in data)
True

or, if you want to do something with the objects of one these types:

for x in data:
if isinstance(x, (str, list, tuple, int)):
print('found')

is there a pythonics way to distinguish Sequences objects like tuple and list from Sequence objects like bytes and str

Good question.

  • There is (currently) no ABC that distinguishes a string from a tuple or other immutable sequence; since there is just one string type in Python 3, the most Pythonic solution is indeed with an isinstance(x, str).
  • Byte sequence types such as bytes and bytearray can be distinguished using the collections.abc.ByteString ABC.

Of course, you could also define your own ABC which includes both str and ByteString, or even give it a __subclasshook__ that checks classes for a method such as capitalize.

Check if something is (not) in a list in Python

The bug is probably somewhere else in your code, because it should work fine:

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

Or with tuples:

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True

how to know if a variable is a tuple, a string or an integer?

You just use:

type(varname)

which will output int, str, float, etc...



Related Topics



Leave a reply



Submit