Python: check if an object is a sequence

Is there an easy way in python to say that something is not a sequence? I tried to just do: if x is not sequence , but python didn't like it

+41
python if-statement sequences sequence
May 30 '10 at
source share
6 answers

iter(x) will raise a TypeError if x cannot be repeated, but it checks for "accepts" sets and dictionaries, although it "rejects" other inconsistencies such as None and numbers.

On the other hand, strings (which most applications want to consider "individual elements" rather than sequences) are actually sequences (so any test, unless specifically used for strings, is going to confirm that they are). Thus, such simple checks are often not enough.

In Python 2.6 and above, abstract base classes were introduced, and among other powerful functions, they offer better, systematic support for such category checking.

 >>> import collections >>> isinstance([], collections.Sequence) True >>> isinstance((), collections.Sequence) True >>> isinstance(23, collections.Sequence) False >>> isinstance('foo', collections.Sequence) True >>> isinstance({}, collections.Sequence) False >>> isinstance(set(), collections.Sequence) False 

You'll notice that strings are still considered a β€œsequence” (since they are), but at least you get dicts and lay aside. If you want to exclude strings from your concept of "being sequences", you can use collections.MutableSequence (but it also excludes tuples that, like strings, are sequences but are not mutable) or do it explicitly:

 import collections def issequenceforme(obj): if isinstance(obj, basestring): return False return isinstance(obj, collections.Sequence) 

Season to taste and serve hot! -)

+53
May 30 '10 at 12:46 a.m.
source share

The Python 2.6.5 documentation describes the following types of sequences: string, Unicode string, list, tuple, buffer, and xrange.

 def isSequence(obj): return type(obj) in [str, unicode, list, tuple, buffer, xrange] 
+6
May 30 '10 at 1:03 a.m.
source share

Why are you doing it? The usual way here is to require a certain type of thing (sequence or number or file-like object, etc.), and then use it without checking anything. In Python, we usually do not use classes to transfer semantic information, but simply use certain methods (this is called duck printing). We also prefer an API where we know exactly what to expect; use keyword arguments, do preprocessing, or define another function if you want to change how the function works.

+4
May 30 '10 at 12:58 a.m.
source share

Since Python sticks to duck input, one approach is to check if the object has any element (method).

The sequence has a length, has a sequence of elements and supports a slice [ doc ]. So it will be like this:

 def is_sequence(obj): t = type(obj) return hasattr(t, '__len__') and hasattr(t, '__getitem__') # additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__') 

These are all special methods, __len__() should return the number of elements, __getitem__(i) should return an element (in sequence it is the i-th element , but not with a display), __getitem__(slice(start, stop, step)) should return a subsequence and __setitem__ and __delitem__ , as you expect. This is such a contract, but whether this object is valid or not depends on whether the object complies with the contract or not.

Note that the above function will also return True for display, for example. dict , since mapping also has these methods. To overcome this, you can do harder work:

 def is_sequence(obj): try: len(obj) obj[0:0] return True except TypeError: return False 

But in most cases you don’t need it, just do what you want, as if the object was a sequence and caught an exception if you want. It is more pythonic.

+4
Jun 25 '15 at 7:00
source share

I think the code snippet below does what you want:

 def is_sequence(obj): return hasattr(type(obj), '__iter__') 
+3
Jul 24. '16 at 6:07
source share

why ask why

try to get the length and if the exception returns false

 def haslength(seq): try: len(seq) except: return False return True 
-2
Aug 26 2018-12-12T00:
source share



All Articles