References, (Im)mutability#
Immutability: Numbers#
Numbers are immutable …
Object of type
int
with value 42Variable
a
points to it (“gives it a name”)The object cannot change its value - there is no method to modify an integer object
⟶ The latter situation is equivalent to the former (which is the implementation)
Modifying An Integer In-Place? (Immutability)#
id(a)
140246684582448
Operator
+=
modifies an integer in-place?a = a+7
modifies an integer in-place?⟶ No, both create new objects!
a += 1
id(a) # <--- different object now
140246684582480
a = a + 7
id(a) # <--- again, different object now
140246684582704
Immutability: Tuples#
a = (42, "xy", 13)
b = a
print(id(a))
print(id(b))
140245962299776
140245962299776
|
And operator
+=
?
a += ('foo', 'bar')
print(a)
print(id(a))
print(id(b))
(42, 'xy', 13, 'foo', 'bar')
140246394411168
140245962299776
⟶ leaves
b
alone
b
(42, 'xy', 13)
Mutability: Lists (1)#
Lists are mutable …
Objects can be modified
E.g. by using
append()
Mutability: Lists (2)#
Danger …
Take care when passing complex data structures
Not passed by copy (as in C++)
Passed by reference (as in Java and C#, for example)
Solution?
Is copy a solution?
⟶ I’d say no!
Being careful is a solution!
a = [1, 2, 3]
b = a[:] # <--- copy
a.append(4)
b
[1, 2, 3]
Shallow Copy#
A list within a list
Create “copy”
a = [1, [1, 2, 3], 2]
b = a[:] # <--- copy
b
[1, [1, 2, 3], 2]
This is only a shallow copy
Modify
a
a[1].append(4)
a
[1, [1, 2, 3, 4], 2]
And
b
?
b
[1, [1, 2, 3, 4], 2]
Reason: nested list has not been copied!
a[1] is b[1]
True
Only first level copied
Shallow copy
a[1]
is a referenceis
: object identity
Deep Copy#
Solution: not easy
Recursive structure traversal
Handling every possible type
Dedicated module in the standard library:
copy
Solution?
import copy
a = [1, [1, 2, 3], 2]
b = copy.deepcopy(a)
a[1] is b[1]
False