The Python docs are a bit ambiguous
sequence
An iterable which supports efficient element access using integer indices via the
__getitem__()
special method and defines a__len__()
method that returns the length of the sequence. Some built-in sequence types are list, str, tuple, and bytes. Note that dict also supports__getitem__()
and__len__()
, but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers.The collections.abc.Sequence abstract base class defines a much richer interface that goes beyond just
__getitem__()
and__len__()
, adding count(), index(),__contains__()
, and__reversed__()
. Types that implement this expanded interface can be registered explicitly using register().
In particular, using abc.collections.Sequence
as the gold standard as recommended by some would mean that, for example, numpy arrays are not sequences:
isinstance(np.arange(6),collections.abc.Sequence)
# False
There is also something called the Sequence Protocol but that appears to be exposed only at the C-API. There the criterion is
int PySequence_Check(PyObject *o)
Return 1 if the object provides sequence protocol, and 0 otherwise. Note that it returns 1 for Python classes with a
__getitem__()
method unless they are dict subclasses since in general case it is impossible to determine what the type of keys it supports. This function always succeeds.
Finally, I don't follow this new (-ish) type annotation business too closely but I would imagine this also would benefit from a clear concept of what a sequence is.
So my question has both a philosophical and a practical side: What exactly is a sequence? and How do I test whether something is a sequence or not? Ideally, in a way that makes numpy arrays sequences. And if I ever start annotating, how would I approach sequences?