Mutable and Immutable types in Python
đˇ Introduction
If you're preparing for Python coding interviews, you've probably heard the terms mutable and immutable. They may sound abstract, but they play a huge role in how Python works under the hood, and understanding them can save you from subtle bugs.
in this post, we'll explore: * What mutability means in Python * Which built-in types are mutable vs immutable * Common interview pitfalls * Why this concept matters for writing clean, efficient code
đˇ What does "Mutable" mean ?
A mutable object can be changed after it's created.
An immutable object cannot be changed once it's created, any "modification" create a new object.
Let's see it in action: we use the built-in function id(object)
to get the memory adress of an object in python.
# Mutable: List
vegetables = ["spinach", "turnip", "pumpkin"]
# object memory adress before change:
print(id(vegetables)) # 135284559366976
# change occur
vegetables.append("bell pepper")
# object memory adress after change:
print(id(vegetables)) # 135284559366976
# âŦī¸ same memory adresse before change occured.
# result:
print(vegetables) # ['spinach', 'turnip', 'pumpkin', 'bell pepper']
Notice that vegetables
memory adress remain the same before and after change occured.
# Immutable: String
name = "Alice"
# object memory adress before change:
print(id(name)) # 133559379123856
# change occur
name = name + " Smith" # Create a *new* string object
# object memory adress after change:
print(id(name)) # 133559374455088
# âŦī¸ different memory adress after change occured.
# result:
print(name) # Alice Smith
Notice that name
memory adress is different before and after change occured.
đˇ Common Mutable and Immutable Types in Python
Type | Mutable? | Example |
---|---|---|
list | â Yes | ["a", "b"] |
dict | â Yes | {"key": "value"} |
set | â Yes | {"a", "b"} |
bytearray | â Yes | bytearray([65, 66]) |
tuple | â No | (1, 2, 3) |
str | â No | "hello" |
int | â No | 42 |
float | â No | 3.14 |
frozenset | â No | frozenset([1, 2]) |
bytes | â No | b"abc" |
đˇ Why it matters
1. Function Arguments
Mutable objects passed to functions can be modified inside the function.
def add_item(my_list):
my_list.append("X")
items = ["A", "B"]
add_item(items)
print(items) # ['A', 'B', 'X'] <-- Modified!
With immutables, this doesn't happen:
def add_one(x):
x += 1
return x
n = 5
print(add_one(n)) # 6
print(n) # 5 (unchanged)
2. Hashability and Dictionary Keys
Immutable objects can be used as dictionary keys or set elements, but mutable ones cannot:
# â
Tuples can be keys
prices = {("apple", "kg"): 3.5}
# â Lists cannot be keys (unashable type)
# prices[[1, 2]] = 4 --> TypeError
This is why you'll often convert lists to tuples before using them as keys.
3. Performance implications
Because immutables cannot change, Python can cache and reuse them
internally, saving memory.
This is why small integers and strings may have the same memory ID:
a = 10
b = 10
print(a is b) # True (same object!)
# Same memory adress
print(id(a)) # 11760968
print(id(b)) # 11760968
But this is not guaranteed for mutables.
đˇ Common Pitfalls in Interviews
â Pitfall 1: Using Mutable Default Arguments
def add_item(item, items=[]): # BAD
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'] <-- Surprise !
â Correct Approach
def add_item(item, items=None):
if items is None:
items = [] # create a new list
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['b']
â Pitfall 2: Assuming Tuples Are Always "Safe"
Tuples are immutable, but they can contain mutable objects!
t = ([],)
t[0].append(1)
print(t) # ([1],) <-- Changed in place!
đˇ Quick Summary
Aspect | Mutable | Immutable |
---|---|---|
Can modify in place? | â Yes | â No |
Can be dict key? | â Usually No | â Yes |
Memory-efficient? | â Often not | â Can be cached |
Examples | list, dict, set | tuple, str, int, float |
đˇ Conclusion
Understanding mutuability is essential for writing clean, bug-free Python code, and it's a topic that comes up frequently in interviews.
* Use mutable types when you need to store data that change over time.
* Use immutable types when you want your data to stay safe, reusable and hashable.
Mastering this distinction will not only improve you interviews answers but also make you a better Python developer.
â Practice Exercise:
- Write a function that safely appends items to a list without risking the mutable default argument pitfall.
- Try creating a tuple containing a list, then mutate the list. Explain why the tuple's "immutability" is misleading.