Time complexity of operations on built-in types¶
This page documents the time-complexity of various operations on built-in types in CPython. Other Python implementations may have different performance characteristics. Additionally, the listed costs assume exact built-in types, as instances of subclasses may have different costs.
We use Big O notation to describe how the running time of an operation grows with the size of its input. Unless stated otherwise, n denotes the number of elements currently in the container, and k is either the value of a parameter or the number of elements in the parameter.
For a pragmatic approach to assessing time complexity, see Ned Batchelder’s Big-O: How Code Slows as Data Grows talk and blog post.
list¶
Lists are mutable sequences; for more detail on the implementation see
How are lists implemented in CPython?. The largest costs come from growing beyond the
current allocation size (because everything must move), or from inserting or
deleting somewhere near the beginning (because everything after that must move).
If you need to add or remove at both ends, consider using a
collections.deque instead.
Operation |
Complexity |
|---|---|
Copy ( |
O(n) |
Append ( |
O(1) |
O(n - k) |
|
O(n - k) |
|
Get item ( |
O(1) |
Set item ( |
O(1) |
Delete item ( |
O(n - k) |
Iteration |
O(n) |
Get slice ( |
O(k) |
Set slice ( |
O(k + n) |
Delete slice ( |
O(n) |
Extend ( |
O(k) |
Sort ( |
O(n log n) |
Multiply ( |
O(nk) |
|
O(n) |
|
O(n) |
Get length ( |
O(1) |
tuple¶
A tuple is an immutable sequence. Because a tuple can never
change, there are no insertion or deletion costs, and making a copy is constant
time as the same object is returned.
Operation |
Complexity |
|---|---|
Copy ( |
O(1) |
Get item ( |
O(1) |
Get slice ( |
O(k) |
Concatenate ( |
O(n + k) |
Multiply ( |
O(nk) |
Iteration |
O(n) |
|
O(n) |
|
O(n) |
Get length ( |
O(1) |
dict, frozendict¶
The times listed for dict objects are average-case times, as they assume the hash function for the objects is sufficiently robust to make collisions uncommon; they also assume the keys used in parameters are selected uniformly at random from the set of all keys. In the worst case, when every key hashes to the same value, each of the O(1) operations below instead takes O(n) time. For more detail on the implementation, see How are dictionaries implemented in CPython?.
A frozendict is immutable, so it does not support setting or deleting
items; the other operations below apply to it at the same costs.
Operation |
Complexity |
|---|---|
|
O(1) |
O(n) |
|
Get item ( |
O(1) |
Set item ( |
O(1) |
Delete item ( |
O(1) |
Iteration [6] |
O(n) |
Get length ( |
O(1) |
set, frozenset¶
See dict as the set and frozenset implementations are
intentionally very similar, and the same hash collision caveat applies.
In the worst case, O(1) operations instead take O(n) time,
and operations that look up every element of an operand degrade accordingly.
A frozenset is immutable, so it does not support adding,
discarding, or the in-place update operations; the others below apply to it at
the same costs.
Operation |
Complexity |
|---|---|
|
O(1) |
Add ( |
O(1) |
Discard ( |
O(1) |
Union ( |
O(len(s) + len(t)) |
O(min(len(s), len(t))) |
|
O(len(s)) |
|
O(min(len(s), len(t))) |
|
Symmetric difference ( |
O(len(s) + len(t)) |
Symmetric difference update ( |
O(len(t)) |
Get length ( |
O(1) |
str, bytes, bytearray¶
str and bytes objects are immutable sequences of characters and
bytes respectively; As with tuples, copying one returns the original object.
A bytearray is mutable, and additionally supports the mutating operations
of list (except sort()), at the same costs. However, deleting at
the front only advances the start of the buffer instead of moving the remaining
bytes, and is amortized O(1).
Operation |
Complexity |
|---|---|
Get item ( |
O(1) |
Get slice ( |
O(k) |
Concatenate ( |
O(n + k) |
Multiply ( |
O(nk) |
Substring search ( |
O(n) |
Encode or decode |
O(n) |
Iteration |
O(n) |
Get length ( |
O(1) |
memoryview¶
memoryview objects allow Python code to access the internal data
of an object that supports the buffer protocol without
copying. In particular, slicing a memory view returns a new view onto the same
buffer.
Operation |
Complexity |
|---|---|
Create ( |
O(1) |
Get item ( |
O(1) |
Get slice ( |
O(1) |
Convert to bytes ( |
O(n) |
Get length ( |
O(1) |
range¶
A range object computes its items on demand from its start, stop and
step values, so most operations do not depend on the length of the range.
Operation |
Complexity |
|---|---|
Get item ( |
O(1) |
Get slice ( |
O(1) |
|
O(1) |
Index and count ( |
O(1) |
Iteration |
O(n) |
|
O(n) |
Get length ( |
O(1) |