Mutable vs Immutable Objects in Python
Understand mutable vs immutable objects in Python with clear examples, id() checks, the default-argument trap, and common interview questions and answers.
Expected Interview Answer
Mutable objects can be changed in place after creation (lists, dicts, sets), while immutable objects cannot be altered once created (int, float, str, tuple, frozenset) — any 'change' produces a brand-new object.
Every Python object has an identity you can see with id(). For a mutable object, operations like list.append() modify the same object, so its id() stays the same and all references see the change. For an immutable object, an operation like s = s + 'x' builds a new object and rebinds the name, leaving the original untouched. This distinction drives how arguments behave when passed to functions, whether an object can be a dict key, and how aliasing bugs appear.
- Immutable objects are hashable, so they can be dict keys and set members
- Immutable objects are safe to share across threads without locks
- Mutable objects allow efficient in-place updates without copying
- Understanding it prevents aliasing and shared-reference bugs
- Explains surprising default-argument and function-mutation behavior
AI Mentor Explanation
Think of a printed scorecard from a finished match versus a live scoreboard. The printed scorecard is immutable: once the match ends you cannot alter a run on it, you can only print a fresh corrected copy. The live scoreboard is mutable: the same board is updated ball by ball, and everyone watching sees each in-place change instantly on that one physical board.
Step-by-Step Explanation
Step 1
Create and inspect identity
Make an object and record id(obj) so you can tell whether later operations reuse it or create a new one.
Step 2
Try an in-place operation
For a list, call append() or use += and check id() — it is unchanged, proving mutation in place.
Step 3
Try the same on an immutable
For a str or tuple, use + to 'add' and check id() — it changed, proving a new object was built.
Step 4
Observe aliasing
Bind two names to one mutable object; mutating through one name is visible through the other.
Step 5
Apply to function calls
Pass a list to a function and mutate it — the caller sees the change; rebind a str inside and the caller does not.
What Interviewer Expects
- A correct list of mutable vs immutable built-in types
- Explanation using id() and object identity
- Awareness of aliasing and shared-reference bugs
- Why immutability enables hashability (dict keys, set members)
- The mutable default argument pitfall
Common Mistakes
- Claiming strings can be modified in place
- Thinking tuples are always fully immutable even when they hold a list
- Saying Python passes by value or strictly by reference instead of pass-by-object-reference
- Using a mutable object like [] as a default argument value
- Confusing rebinding a name with mutating the object
Best Answer (HR Friendly)
“In Python, some things can be edited after you make them and some cannot. Lists and dictionaries are editable in place, while numbers, text, and tuples are fixed — changing them actually creates a new value. Knowing which is which helps you avoid bugs where two variables accidentally share and change the same data.”
Code Example
nums = [1, 2, 3]
print(id(nums))
nums.append(4) # mutates in place
print(id(nums)) # same id -> same object
text = "hi"
print(id(text))
text = text + "!" # builds a new string
print(id(text)) # different id -> new objectdef bad(item, bucket=[]): # default list is created once
bucket.append(item)
return bucket
print(bad(1)) # [1]
print(bad(2)) # [1, 2] <- surprise, shared list
def good(item, bucket=None): # correct pattern
if bucket is None:
bucket = []
bucket.append(item)
return bucketFollow-up Questions
- Why can a tuple be used as a dictionary key but a list cannot?
- How does Python pass arguments — by value, by reference, or something else?
- Can a tuple ever effectively change, and how?
- What is the difference between == and is?
- How do copy.copy and copy.deepcopy relate to mutability?
MCQ Practice
1. Which of the following is an immutable type in Python?
Tuples are immutable; lists, dicts, and sets can all be modified in place.
2. What does calling a_list.append(4) do to the object's id()?
append() mutates the list in place, so its identity (id) is unchanged.
3. Why can an immutable object be used as a dictionary key?
Dict keys must be hashable; immutability guarantees a stable hash for the object's lifetime.
Flash Cards
Name three immutable built-in types. — int, float, str, tuple, frozenset, and bytes are immutable.
Name three mutable built-in types. — list, dict, set, and bytearray are mutable.
How do you check if an operation mutated an object? — Compare id(obj) before and after — same id means in-place mutation, different id means a new object.
Why avoid a mutable default argument? — The default is created once at definition time and shared across calls, so mutations accumulate between calls.