Tuple Operations Complexity¶
The tuple type is an immutable, ordered sequence. Being immutable allows various optimizations in CPython.
Time Complexity¶
| Operation | Time | Notes |
|---|---|---|
len() |
O(1) | Direct lookup |
access[i] |
O(1) | Direct indexing |
index(x) |
O(n) | Linear search |
count(x) |
O(n) | Linear scan |
in (membership) |
O(n) | Linear search |
copy() |
O(1) | Just increments reference count |
x + y (concatenation) |
O(m+n) | m, n are lengths |
t * n (repetition) |
O(n*len(t)) | Creates new tuple |
hash() |
O(n) | Computes hash by iterating all elements |
reversed() |
O(1) | Iterator, not materialized |
tuple() constructor |
O(n) | n = iterable length |
slice [::2] |
O(k) | k = slice length |
Space Complexity¶
| Operation | Space |
|---|---|
| Creation | O(1) reference |
| Copy | O(1) (same object) |
| Concatenation | O(m+n) new tuple |
| Repetition | O(n*len(t)) |
| Reversed iterator | O(1) |
Implementation Details¶
Immutability Advantages¶
# Tuples are hashable - can be dict keys or set members
d = {(1, 2): 'point', (3, 4): 'another'}
s = {(0, 0), (1, 1)}
# Lists cannot - they're mutable
# d[[1, 2]] = 'fails' # TypeError: unhashable type
Hash Computation¶
# hash() computes hash value by iterating all elements
t = (1, 2, 3)
h1 = hash(t) # O(n) - computes by iterating elements
# Note: Unlike strings, tuples do NOT cache their hash
# Each call recomputes: O(n) every time
h2 = hash(t) # O(n) - recomputes hash
Reference vs Copy¶
# Tuple "copy" doesn't copy - returns same object
t1 = (1, 2, 3)
t2 = tuple(t1)
print(t1 is t2) # True - same object in memory!
# This is safe because tuples are immutable
Performance Compared to Lists¶
# List access: O(1) with bounds checking
lst = [0] * 1000000
value = lst[500000] # O(1)
# Tuple access: O(1) same as list
tup = tuple(lst)
value = tup[500000] # O(1)
# But tuple creation from list: O(n)
tup = tuple(lst) # O(n) - must copy all elements
Version Notes¶
- All versions: Core complexity stable
- Python 3.8+: Improved tuple unpacking in some cases
- Python 3.11+: Adaptive specialization may optimize repeated tuple operations
Implementation Comparison¶
CPython¶
Direct sequence type with immutability optimizations.
PyPy¶
JIT compilation with escape analysis may further optimize.
Jython¶
Similar characteristics, backed by Java arrays.
Best Practices¶
✅ Do:
- Use tuples for immutable sequences
- Use tuples as dict keys when you need structured keys
- Use tuples for multiple return values
- Use tuple unpacking:
x, y = point
❌ Avoid:
- Repeated concatenation:
t += (item,)in loops - use list instead - Creating tuples from large iterables in loops
- Assuming tuple copy is fast - it still references same elements
Common Patterns¶
Named Return Values¶
# Basic tuples
def get_coordinates():
return (10, 20)
x, y = get_coordinates()
# Better: use named tuples
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
def get_point():
return Point(10, 20)
p = get_point()
print(p.x, p.y) # More readable
Tuple vs List Performance¶
# Tuple creation: O(n) once, then fast access
tup = tuple(range(1000000))
for i in range(1000):
x = tup[i] # O(1)
# List creation: O(n) once, then fast access
lst = list(range(1000000))
for i in range(1000):
x = lst[i] # O(1)
# Both have same access time; tuple is hashable and immutable
Related Types¶
- List - Mutable alternative
- Namedtuple - Tuples with named fields
- Dataclass - More powerful structure type