Mutable types là kiểu dữ liệu có thể thay đổi giá trị tại chỗ sau khi tạo; immutable types là kiểu không thể thay đổi sau khi tạo, mọi thao tác "sửa" thực chất tạo ra object mới. Ví dụ: list, dict, set, bytearray là mutable; int, float, str, tuple, frozenset, bytes là immutable.
Cơ chế nằm ở việc object có hỗ trợ thay đổi nội dung bộ nhớ mà không đổi id hay không. Với list, bạn gọi lst.append(1) thì id(lst) không đổi. Với str, bạn nối chuỗi s += 'a' thì Python tạo object str mới và gán lại biến; id có thể đổi, và object cũ được thu hồi.
Ví dụ:
lst = [1, 2]
print(id(lst)) # id ban đầu
lst.append(3)
print(id(lst)) # id giữ nguyên
s = "ab"
print(id(s)) # id ban đầu
s += "c"
print(id(s)) # id thường đổi, vì tạo str mớiEdge case hay gặp: dùng mutable làm default argument. def func(lst=[]) tạo một list duy nhất lúc định nghĩa hàm, nên mọi lần gọi không truyền lst đều dùng chung list đó, gây lỗi khó phát hiện. Cách sửa là dùng None rồi tạo list mới trong thân hàm.
Lưu ý: tuple chứa mutable object (ví dụ tuple chứa list) vẫn là immutable về cấu trúc, nhưng phần tử bên trong có thể đổi; điều này dễ gây nhầm khi kiểm tra hashability.