Python mutable vs immutable types

PYTHON Published Updated 3 mins read By Leon Wei
Python mutable vs immutable types cover image

Quick summary

Summarize this blog with AI

A name refers to an object. Rebinding a name changes that reference; mutating an object changes the object seen by every alias. Lists, dictionaries and sets are mutable. Numbers, strings and tuples are immutable, but an immutable container can still refer to mutable objects. These Python 3.12.14 fixtures make the resulting state explicit.

Distinguish mutation from rebinding

original = [1, 2]
alias = original
alias.append(3)
print(original, original is alias)
alias = [9]
print(original, alias)
number = 10
other = number
other += 1
print(number, other)

Expected output:

[1, 2, 3] True
[1, 2, 3] [9]
10 11

Assignment did not copy the list. Rebinding alias afterward did not undo the earlier append. Integers cannot change their numeric value in place, so the increment binds other to a different integer object. Do not infer these semantics from printed memory addresses or small-integer caching.

A shallow copy still shares nested objects

from copy import deepcopy
source = {"tags": ["sql"], "count": 1}
shallow = source.copy()
deep = deepcopy(source)
shallow["tags"].append("python")
shallow["count"] = 2
print(source)
print(shallow)
print(deep)
print(source["tags"] is shallow["tags"], source["tags"] is deep["tags"])

Expected output:

{'tags': ['sql', 'python'], 'count': 1}
{'tags': ['sql', 'python'], 'count': 2}
{'tags': ['sql'], 'count': 1}
True False

A shallow copy creates a new outer dictionary but retains its referenced values. deepcopy recursively copies this ordinary nested data structure; it is not a universal way to duplicate sockets, files, database sessions or arbitrary external resources. Custom classes can also customize copying. Copy only what the function’s ownership contract requires.

A tuple cannot replace a slot, but its nested list can change

record = (["sql"], "Ada")
record[0].append("python")
print(record)
try:
    record[1] = "Ben"
except TypeError:
    print("tuple slot assignment is forbidden")
try:
    hash(record)
except TypeError:
    print("tuple contains an unhashable list")

Expected output:

(['sql', 'python'], 'Ada')
tuple slot assignment is forbidden
tuple contains an unhashable list

Tuple immutability concerns its references, not a promise that everything reachable is frozen. This tuple is not hashable because one element is a list. Conversely, custom class instances can be mutable and hashable, so “mutable means unhashable” is not a universal rule; hash/equality behavior must remain suitable for dictionary and set use.

Allocate a fresh default at call time

def bad_collect(value, items=[]):
    items.append(value)
    return items

print(bad_collect("a"))
print(bad_collect("b"))

def collect(value, items=None):
    if items is None:
        items = []
    items.append(value)
    return items

print(collect("a"), collect("b"))
owned = []
print(collect("c", owned), owned)

Expected output:

['a']
['a', 'b']
['a'] ['b']
['c'] ['c']

The default list is created when the function definition executes, then reused. The repaired function creates a new list only when no list was supplied. It intentionally mutates a caller-provided list, including an empty one. If that mutation is undesirable, copy the supplied list instead and document whether nested elements remain shared. Do not use items = items or [] when an empty caller-owned list must be retained.

Write an ownership sentence for your function

State whether a function mutates its argument, returns a new outer object, or makes an independent deep copy of supported data. Then test both the return value and the caller’s state. Neither mutability nor immutability guarantees better speed; allocation, aliasing and workload matter. For identity tests see identity versus equality; for tuple syntax see the tuple guide.

References and next steps

Copy semantics, Default arguments, Data model.

Interview Prep

Begin Your SQL, Python, and R Journey

Master 230 interview-style coding questions and build the data skills needed for analyst, scientist, and engineering roles.

Related Articles

All Articles
Pygame a primer cover image
python Apr 29, 2024

Pygame a primer

Learn how Pygame creates fully-featured games and multimedia applications, and simplifies graphics rendering, sound management, and game logic w…