GICT knowledge base
Python Tuple Basics: Immutability, Unpacking, and Hashable Keys
Published
A Python tuple is an ordered sequence whose item references cannot be replaced, added, or removed after creation. It is useful for a fixed record such as a host and port. Immutability is not the same as encryption, access control, or a guarantee that every object inside the tuple is unchangeable.
The examples below use ordinary Python 3 and require no packages or network access. Each code block is independent unless stated otherwise.
Create a tuple
A comma creates a nonempty tuple. Parentheses group the expression; empty parentheses create the empty tuple. The comma matters when there is only one item.
endpoint = ("web.example", 443)
single = (443,)
not_a_tuple = (443)
empty = ()
assert isinstance(endpoint, tuple)
assert isinstance(single, tuple)
assert isinstance(not_a_tuple, int)
assert len(empty) == 0
You can also convert an iterable: tuple([80, 443]) produces (80, 443). Conversion is shallow; it does not recursively freeze nested lists or dictionaries.
Read, slice, and unpack
endpoint = ("web.example", 443)
host, port = endpoint
print(host) # web.example
print(endpoint[-1]) # 443
print(endpoint[:1]) # ('web.example',)
assert port == 443
Indexing an absent position raises IndexError. Slicing can return an empty tuple without raising that error. Unpacking into two variables requires exactly two values; use a starred target when the number of remaining items varies.
primary, *fallbacks = ("web-a", "web-b", "web-c")
assert primary == "web-a"
assert fallbacks == ["web-b", "web-c"]
Loop and inspect
ports = (80, 443, 443)
for position, port in enumerate(ports):
print(position, port)
assert len(ports) == 3
assert ports.count(443) == 2
assert ports.index(443) == 1
assert 22 not in ports
index() returns the first matching position and raises ValueError if the value is absent. Tuples permit duplicates. For more iteration patterns, see How to Loop Through Tuples in Python.
What immutability does and does not mean
endpoint = ("web.example", 443)
try:
endpoint[1] = 8443
except TypeError:
print("Tuple items cannot be reassigned")
A mutable item inside a tuple can still change. Another reference to that same item will observe the change:
ports = [80]
record = ("web.example", ports)
ports.append(443)
assert record == ("web.example", [80, 443])
Consequently, wrapping shared mutable data in a tuple does not make it thread-safe or read-only. Choose an appropriate representation and synchronization strategy for the objects you actually share.
Use a tuple as a dictionary key only when it is hashable
A tuple is hashable only if all its items are hashable. A tuple of strings and integers works; one containing a list does not. Hashability, rather than a blanket rule about all immutable objects, is the requirement for a dictionary key or set member. See Python’s definition of hashable.
labels = {("web.example", 443): "HTTPS"}
assert labels[("web.example", 443)] == "HTTPS"
try:
hash(("web.example", [443]))
except TypeError:
print("The nested list makes this tuple unhashable")
Return a small record from a function
def default_endpoint():
return "web.example", 443
host, port = default_endpoint()
assert (host, port) == ("web.example", 443)
For a large record, named fields in a dataclass or named tuple can be clearer than remembering many numeric positions. For a collection that grows or changes frequently, a list is usually more straightforward. Do not choose tuples based on an unmeasured claim that they make every operation faster.
Verification: All eight code blocks were executed with Python 3.12.14, including the expected TypeError cases. The Python tutorial provides the underlying sequence semantics. To replace values without changing the original tuple, see Creating an Updated Tuple in Python.
Related guides
How to Deploy a FastAPI App with Gunicorn and Nginx
Deploy FastAPI behind Nginx with Gunicorn and systemd. Separate application packages, check HTTPS and verify worker replacement and application health.
PythonLearn How to Modify Python Dictionary Values Easily
Learn how to modify Python dictionary values effectively with various methods, including direct assignment, update(), and comprehensions, along with common mistakes to...
PythonPython Set Copy Tutorial: Avoid Common Mistakes and Data Errors
Learn how to copy sets in Python safely and efficiently while avoiding common mistakes. Explore methods like copy(), set(), and deepcopy().
PythonDifferent Methods to Loop Through Sets in Python (Beginner-Friendly Guide)
Learn diverse methods to loop through sets in Python, including practical examples and use cases, ideal for beginners looking to master set operations.
