Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: check if an object is a sequence

In python is there an easy way to tell if something is not a sequence? I tried to just do: if x is not sequence but python did not like that

like image 749
nicotine Avatar asked May 30 '10 00:05

nicotine


People also ask

How do you check if an object is a list in Python?

Given an object, the task is to check whether the object is list or not. if isinstance (ini_list1, list ): print ( "your object is a list !" )

What is a sequence object in Python?

A sequence is a positionally ordered collection of items. And you can refer to any item in the sequence by using its index number e.g., s[0] and s[1] . In Python, the sequence index starts at 0, not 1. So the first element is s[0] and the second element is s[1] . If the sequence s has n items, the last item is s[n-1] .


2 Answers

iter(x) will raise a TypeError if x cannot be iterated on -- but that check "accepts" sets and dictionaries, though it "rejects" other non-sequences such as None and numbers.

On the other hands, strings (which most applications want to consider "single items" rather than sequences) are in fact sequences (so, any test, unless specialcased for strings, is going to confirm that they are). So, such simple checks are often not sufficient.

In Python 2.6 and better, abstract base classes were introduced, and among other powerful features they offer more good, 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 note strings are still considered "a sequence" (since they are), but at least you get dicts and sets out of the way. If you want to exclude strings from your concept of "being sequences", you could use collections.MutableSequence (but that also excludes tuples, which, 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!-)

PS: For Python 3, use str instead of basestring, and for Python 3.3+: Abstract Base Classes like Sequence have moved to collections.abc.

like image 98
Alex Martelli Avatar answered Oct 12 '22 13:10

Alex Martelli


For Python 3 and 2.6+, you can check if it's a subclass of collections.Sequence:

>>> import collections >>> isinstance(myObject, collections.Sequence) True 

In Python 3.7 you must use collections.abc.Sequence (collections.Sequence will be removed in Python 3.8):

>>> import collections.abc >>> isinstance(myObject, collections.abc.Sequence) True 

However, this won't work for duck-typed sequences which implement __len__() and __getitem__() but do not (as they should) subclass collections.Sequence. But it will work for all the built-in Python sequence types: lists, tuples, strings, etc.

While all sequences are iterables, not all iterables are sequences (for example, sets and dictionaries are iterable but not sequences). Checking hasattr(type(obj), '__iter__') will return True for dictionaries and sets.

like image 44
Al Sweigart Avatar answered Oct 12 '22 14:10

Al Sweigart