पाठ 2 / 25
Python's Object Model: References, Mutability and Copies
Understand names, references, mutability, identity and copying.
Names point to objects
In Python, variables are names bound to objects; assignment never copies data, it makes another name refer to the same object. Every object has an identity (id(x), compared with is), a type and a value (compared with ==). Objects are mutable (list, dict, set, bytearray, most user classes) or immutable (int, float, str, tuple, frozenset, bytes). Mutability matters for data structures: two names for one list see each other's changes (aliasing); a mutable default argument (def f(items=[])) is created once and shared between calls; and only hashable objects (generally immutable ones) can be dictionary keys or set members. Containers hold references, so [[0] * 3] * 3 creates three references to the same inner list. Copying: list(x), x[:], x.copy() and copy.copy make shallow copies (new container, same element objects), while copy.deepcopy recursively copies nested mutable objects. Small integers and some strings may be cached by CPython, which is why is must never be used to compare values; use is only for None and sentinel objects.
Aliasing, shallow and deep copies
Common surprises and how to avoid them.
import copy
cart = ["pen", "ink"]
same_cart = cart # another name, same list
same_cart.append("pad")
print(cart) # ['pen', 'ink', 'pad']
print(cart is same_cart) # True
grid_bad = [[0] * 3] * 3 # three references to ONE row
grid_bad[0][0] = 1
print(grid_bad) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
grid = [[0] * 3 for _ in range(3)] # three distinct rows
grid[0][0] = 1
print(grid) # [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
orders = {"asha": ["o1", "o2"]}
shallow = copy.copy(orders)
deep = copy.deepcopy(orders)
orders["asha"].append("o3")
print(shallow["asha"]) # ['o1', 'o2', 'o3']: inner list is shared
print(deep["asha"]) # ['o1', 'o2']: fully independent
def add_item(item, items=None): # never use a mutable default like items=[]
if items is None:
items = []
items.append(item)
return items
print(add_item("pen"), add_item("ink")) # ['pen'] ['ink']Labels on boxes
A Python variable is a luggage label tied to a box, not the box itself. Tying a second label to the same box does not create a second box; whatever you put in it is visible through both labels.
त्वरित जाँच: Why does `[[0] * 3] * 3` behave unexpectedly when you modify one row?
- Lists cannot be nested
- Integers are mutable
- It creates a tuple
- The outer list holds three references to the same inner list
Answer
The outer list holds three references to the same inner list — Multiplying a list repeats references, not copies.