Mutation in Python
Mutation occurs when we change the value stored at a location. The simplest locations are variables.
>>> x = 123 >>> x 123 >>> y = x >>> y 123 >>> y = 456 >>> y 456 >>> x 123 >>>
However we can also refer to locations in structures such as lists, tuples, etc.
>>> x = [5,4,3,2,1] >>> x[2] 3 >>> y = (5,4,3,2,1) >>> y[3] 2 >>>
- Remember that lists and dictionaries are mutable whereas tuples and strings are not.
We can mutate a value within a mutable structure:
>>> number_string = 'zero one two three four five six seven eight nine' >>> number_list = number_string.split() >>> number_list ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'] >>> number_list[5] 'five' >>> number_list[5] = 'vijf' >>> number_list ['zero', 'one', 'two', 'three', 'four', 'vijf', 'six', 'seven', 'eight', 'nine']
But note that structure is shared. Here
nummer_lijstis assigned to the same structure asnumber_list. This meal that when part ofnumber_listis mutated, that same part ofnummer_lijstis also mutated.>>> number_list = number_string.split() >>> nummer_lijst = number_list >>> number_list ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'] >>> nummer_lijst ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'] >>> number_list[5] = 'vijf' >>> number_list ['zero', 'one', 'two', 'three', 'four', 'vijf', 'six', 'seven', 'eight', 'nine'] >>> nummer_lijst ['zero', 'one', 'two', 'three', 'four', 'vijf', 'six', 'seven', 'eight', 'nine'] >>>
This can be pictured as follows
>>> l1 = [1,2,3] >>> l2 = l1 >>> l3 = [1,2,3] >>> l1[2] = 'three' >>> l1 [1, 2, 'three'] >>> l2 [1, 2, 'three'] >>> l3 [1, 2, 3]
- This behaviour holds not only for lists but for all mutable Python structures and for structures in structures in structures…
Note however that the
+and*operators on sequences always produce new sequences which do not share structure with their operands>>> l = [1,2,3] >>> m = l + l >>> m [1, 2, 3, 1, 2, 3] >>> n = l * 4 >>> n [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> l[0] = 8 >>> m [1, 2, 3, 1, 2, 3] >>> n [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3] >>> l [8, 2, 3]
You can check whether two structures are equal using the
==operator, and whether they are identical using theisoperator. Identity is a stricter notion that equality. If two objects are identical they are always equal.>>> l1 = [1,2,3] >>> l2 = l1 >>> l3 = [1,2,3] >>> l1 is l2 True >>> l1 is l3 False >>> l1 == l2 True >>> l1 == l3 True
In fact, each Python object has a unique identity which you can access using the
idfunction>>> id(l1) 140737352275080 >>> id(l2) 140737352275080 >>> id(l3) 140737352276160