Brief introduction to typing in Python

Skip ahead if you know what structural typing, nominal typing and duck typing are.

I think much of the confusion arises from the fact that typing was a provisional module between versions 3.5 and 3.6. And was still subject to change between versions 3.7 and 3.8. This means there has been a lot of flux in how Python has sought to deal with typing through type annotations.

It also doesn't help that python is both duck-typed and nominally typed. That is, when accessing an attribute of an object, Python is duck-typed. The object will only be checked to see if it has an attribute at runtime, and only when immediately requested. However, Python also has nominal typing features. Nominal typing is where one type is declared to be a subclass of another. This can be through inheritance, or with the register() method of ABCMeta.

typing originally introduced its types using the idea of nominal typing. As of 3.8 it is trying to allow for the more pythonic structural typing. Structural typing is related to duck-typing, except that it is taken into consideration at "compile time" rather than runtime. For instance, when a linter is trying to detect possible type errors -- such as if you were to pass a dict to a function that only accepts sequences like tuples or list. With structural typing, a class B should be considered a subtype of A if it implements the all the methods of A, regardless of whether it has been declared to be a subtype of A (as in nominal typing).

Answer

sequences (little s) are a duck type. A sequence is any ordered collection of objects that provides random access to its members. Specifically, if it defines __len__ and __getitem__ and uses integer indices between 0 and n-1 then it is a sequence. A Sequence (big s) is a nominal type. That is, to be a Sequence, a class must be declared as such, either by inheriting from Sequence or being registered as a subclass.

A numpy array is a sequence, but it is not a Sequence as it is not registered as a subclass of Sequence. Nor should it be, as it does not implement the full interface promised by Sequence (things like count() and index() are missing).

It sounds like you want is a structured type for a sequence (small s). As of 3.8 this is possible by using protocols. Protocols define a set of methods which a class must implement to be considered a subclass of the protocol (a la structural typing).

from typing import Protocol
import numpy as np

class MySequence(Protocol):
    def __getitem__(self, index):
        raise NotImplementedError
    def __len__(self):
        raise NotImplementedError
    def __contains__(self, item):
        raise NotImplementedError
    def __iter__(self):
        raise NotImplementedError

def f(s: MySequence):
    for i in range(len(s)):
        print(s[i], end=' ')
    print('end')

f([1, 2, 3, 4]) # should be fine
arr: np.ndarray = np.arange(5)
f(arr) # also fine
f({}) # might be considered fine! Depends on your type checker

Protocols are fairly new, so not all IDEs/type checkers might support them yet. The IDE I use, PyCharm, does. It doesn't like f({}), but it is happy to consider a numpy array a Sequence (big S) though (perhaps not ideal). You can enable runtime checking of protocols by using the runtime_checkable decorator of typing. Be warned, all this does is individually check that each of the Protocols methods can be found on the given object/class. As a result, it can become quite expensive if your protocol has a lot of methods.

Answer from Dunes on Stack Overflow
๐ŸŒ
Real Python
realpython.com โ€บ python-sequences
Python Sequences: A Comprehensive Guide โ€“ Real Python
March 18, 2026 - A sequence is a data structure that contains items arranged in order, and you can access each item using an integer index that represents its position in the sequence. You can always find the length of a sequence. Here are some examples of sequences from Pythonโ€™s basic built-in data types:
๐ŸŒ
Python Like You Mean It
pythonlikeyoumeanit.com โ€บ Module2_EssentialsOfPython โ€บ SequenceTypes.html
Sequence Types โ€” Python Like You Mean It
Given a sequence, x, and a valid ... to return the index 0. ... We have been introduced to three Python types that are sequential in nature: strings, lists, and tuples....
Discussions

python - What exactly is a Sequence? - Stack Overflow
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. More on stackoverflow.com
๐ŸŒ stackoverflow.com
Question regarding type-hinting Collection types
So, logic says that here: list[str | int] It means that it's a list that contains ONLY strings OR ONLY integers. Right? Wrong, actually. This is a list of mixed str and int. What you mean would be written list[str] | list[int]. More on reddit.com
๐ŸŒ r/Python
10
8
August 26, 2023
i keep getting this message saying that i cant multiply a sequence with a non-int of type

The error message is because on the line suggested you are attempting to multiply two strings.

As the other comment suggests, keep everything in number (int or float) until you need to display it.

More on reddit.com
๐ŸŒ r/pythonhelp
5
3
April 28, 2022
How to check is a sequence of given numbers appears in a list?
Here's one way to do it: >>> passing = [10, 15, 2, 5 ,1 , 2, 3] >>> failing = [10, 15, 2, 5 ,1 , 2, 5] >>> pattern = [1, 2, 3] >>> def isin(pattern, sequence): ... for i in range(len(sequence) - len(pattern) + 1): ... if sequence[i:i+len(pattern)] == pattern: ... return True ... return False ... >>> isin(pattern, passing) True >>> isin(pattern, failing) False And if you are doing this for school, they probably expect something like this: >>> def isin_rec(p, s): ... return (len(p) <= len(s)) and ((s[:len(p)] == p) or isin_rec(p, s[1:])) More on reddit.com
๐ŸŒ r/learnpython
18
17
November 29, 2021
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ builtins โ€บ stdtypes.html
Built-in Types โ€” Python 3.14.7 documentation
If a container objectโ€™s __iter__() ... documentation for the yield expression. There are three basic sequence types: lists, tuples, and range objects....
Top answer
1 of 3
18

Brief introduction to typing in Python

Skip ahead if you know what structural typing, nominal typing and duck typing are.

I think much of the confusion arises from the fact that typing was a provisional module between versions 3.5 and 3.6. And was still subject to change between versions 3.7 and 3.8. This means there has been a lot of flux in how Python has sought to deal with typing through type annotations.

It also doesn't help that python is both duck-typed and nominally typed. That is, when accessing an attribute of an object, Python is duck-typed. The object will only be checked to see if it has an attribute at runtime, and only when immediately requested. However, Python also has nominal typing features. Nominal typing is where one type is declared to be a subclass of another. This can be through inheritance, or with the register() method of ABCMeta.

typing originally introduced its types using the idea of nominal typing. As of 3.8 it is trying to allow for the more pythonic structural typing. Structural typing is related to duck-typing, except that it is taken into consideration at "compile time" rather than runtime. For instance, when a linter is trying to detect possible type errors -- such as if you were to pass a dict to a function that only accepts sequences like tuples or list. With structural typing, a class B should be considered a subtype of A if it implements the all the methods of A, regardless of whether it has been declared to be a subtype of A (as in nominal typing).

Answer

sequences (little s) are a duck type. A sequence is any ordered collection of objects that provides random access to its members. Specifically, if it defines __len__ and __getitem__ and uses integer indices between 0 and n-1 then it is a sequence. A Sequence (big s) is a nominal type. That is, to be a Sequence, a class must be declared as such, either by inheriting from Sequence or being registered as a subclass.

A numpy array is a sequence, but it is not a Sequence as it is not registered as a subclass of Sequence. Nor should it be, as it does not implement the full interface promised by Sequence (things like count() and index() are missing).

It sounds like you want is a structured type for a sequence (small s). As of 3.8 this is possible by using protocols. Protocols define a set of methods which a class must implement to be considered a subclass of the protocol (a la structural typing).

from typing import Protocol
import numpy as np

class MySequence(Protocol):
    def __getitem__(self, index):
        raise NotImplementedError
    def __len__(self):
        raise NotImplementedError
    def __contains__(self, item):
        raise NotImplementedError
    def __iter__(self):
        raise NotImplementedError

def f(s: MySequence):
    for i in range(len(s)):
        print(s[i], end=' ')
    print('end')

f([1, 2, 3, 4]) # should be fine
arr: np.ndarray = np.arange(5)
f(arr) # also fine
f({}) # might be considered fine! Depends on your type checker

Protocols are fairly new, so not all IDEs/type checkers might support them yet. The IDE I use, PyCharm, does. It doesn't like f({}), but it is happy to consider a numpy array a Sequence (big S) though (perhaps not ideal). You can enable runtime checking of protocols by using the runtime_checkable decorator of typing. Be warned, all this does is individually check that each of the Protocols methods can be found on the given object/class. As a result, it can become quite expensive if your protocol has a lot of methods.

2 of 3
1

I think the most practical way to define a sequence in Python is 'A container that supports indexing with integers'.

The Wikipedia definition also holds:

a sequence is an enumerated collection of objects in which repetitions are allowed and order does matter.

To validate if an object is a sequence, I would emulate the logic from the Sequence Protocol:

hasattr(test_obj, "__getitem__") and not isinstance(test_obj, collections.abc.Mapping) 
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ article โ€บ python-sequence-types
Python Sequence Types
March 25, 2026 - In Python programming, sequence types are fundamental data structures that hold an ordered collection of items. The main sequence types include Lists, Strings, Tuples, and Range objects.
๐ŸŒ
Medium
medium.com โ€บ nerd-for-tech โ€บ sequence-type-and-iterables-in-python-4e2ca6b08981
Sequence Type and Iterables in Python | by Shilpa Sreekumar | Medium
January 13, 2024 - Sequence Type in python are strings, lists, tuples, byte sequences, byte arrays and range objects which are indexable and we can iterateโ€ฆ
๐ŸŒ
Python Geeks
pythongeeks.org โ€บ python geeks โ€บ learn python โ€บ sequences in python with types and examples
Sequences in Python with Types and Examples - Python Geeks
June 9, 2021 - Sequences in Python - A sequence is a succession of values bound together by a container that reflects their type. Learn more about it.
Find elsewhere
๐ŸŒ
Art of Problem Solving
artofproblemsolving.com โ€บ wiki โ€บ index.php โ€บ Sequence_(Python)
Sequence (Python) - AoPS Wiki
Lists are the most versatile sequence type. The elements of a list can be any object, and lists are mutable - they can be changed. Elements can be reassigned or removed, and new elements can be inserted. Tuples are like lists, but they are immutable - they can't be changed. Strings are a special type of sequence that can only store characters, and they have a special notation.
๐ŸŒ
Python Tutorial
pythontutorial.net โ€บ home โ€บ advanced python โ€บ python sequences
Python Sequences
March 27, 2025 - Python has the following built-in sequence types: lists, bytearrays, strings, tuples, range, and bytes.
๐ŸŒ
Python
docs.python.org โ€บ 2.0 โ€บ lib โ€บ typesseq.html
2.1.5 Sequence Types
There are six sequence types: strings, Unicode strings, lists, tuples, buffers, and xrange objects. Strings literals are written in single or double quotes: 'xyzzy', "frobozz". See chapter 2 of the Python Reference Manual for more about string literals. Unicode strings are much like strings, ...
๐ŸŒ
TechVidvan
techvidvan.com โ€บ tutorials โ€บ python-sequences
Python Sequences - Types, Operations, and Functions - TechVidvan
January 13, 2020 - In Python programming, sequences ... supports six different types of sequences. These are strings, lists, tuples, byte sequences, byte arrays, and range objects....
๐ŸŒ
Wikibooks
en.wikibooks.org โ€บ wiki โ€บ Python_Programming โ€บ Sequences
Python Programming/Sequences - Wikibooks, open books for an open world
There are seven sequence types: strings, bytes, lists, tuples, bytearrays, buffers, and range objects. Dictionaries and sets are containers for sequential data. ... We already covered strings, but that was before you knew what a sequence is. In other languages, the elements in arrays and sometimes ...
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ what-is-a-sequence-data-type-in-python
What is a sequence data type in Python?
May 16, 2025 - Sequence data types in Python are ordered collections that allow you to store and access multiple items using indexing. The three main sequence data types are lists, strings, and tuples.
๐ŸŒ
Scaler
scaler.com โ€บ home โ€บ topics โ€บ what are sequence data types in python?
What are Sequence Data Types in python? - Scaler Topics
May 4, 2023 - We have four built-in (general) data structures in python namely - lists, dictionaries, tuples and sets. Apart from these, we have some user-defined data structures in python like stacks, queues, trees, linked lists, graphs, and hashmaps. There are mainly six types of sequence data type in Python programming language, they are as follows:
๐ŸŒ
Medium
medium.com โ€บ @sarahmbs โ€บ python-sequence-types-1-23693a1097d8
Python Sequence Types #1. Main insights from Fluent Python | by Sarah | Medium
March 24, 2024 - In Python 3, this no longer happens, so list comps work like functions, each variable inside the listcomp have their own local scope. Genexps are used to initialize tuples, arrays, and other types of sequences.
๐ŸŒ
NxtWave
ccbp.in โ€บ blog โ€บ articles โ€บ sequence-in-python
Sequence in Python: Types, Methods & Examples
Sequences' primary characteristic is their indexed elements, which allow you to recover any item by using a number that indicates where it is in the sequence. Lists, tuples, strings, and ranges are among the sequence types available in Python.
๐ŸŒ
DataFlair
data-flair.training โ€บ blogs โ€บ python-sequence
Python Sequence and Collections - Operations, Functions, Methods - DataFlair
April 21, 2026 - In this Python Sequence Tutorial, we will discuss 6 types of Sequence: String, list, tuples, Byte sequences, byte array, and range object.
๐ŸŒ
Python
docs.python.org โ€บ 2.4 โ€บ lib โ€บ typesseq.html
2.3.6 Sequence Types -- str, unicode, list, tuple, buffer, xrange
October 18, 2006 - There are six sequence types: strings, Unicode strings, lists, tuples, buffers, and xrange objects. String literals are written in single or double quotes: 'xyzzy', "frobozz". See chapter 2 of the Python Reference Manual for more about string literals. Unicode strings are much like strings, ...
๐ŸŒ
The Python Coding Stack
thepythoncodingstack.com โ€บ the python coding stack โ€บ sequences in python (data structure categories #2)
Sequences in Python (Data Structure Categories #2)
June 25, 2024 - And you're likely to see common ... the headline difference between the two terms: A Python sequence is an iterable that you can index using an integer....
๐ŸŒ
Real Python
realpython.com โ€บ ref โ€บ glossary โ€บ sequence
sequence | Python Glossary โ€“ Real Python
Sequences are fundamental in Python programming because they provide a way to handle collections of data efficiently. With sequences, you can perform operations like concatenation, repetition, and membership testing. You can also use built-in functions like len(), min(), and max() to perform common tasks. Hereโ€™s a quick example of using a list, which is a sequence data type in Python: