# References, (Im)mutability¶

## Immutability: Numbers¶

Numbers are immutable

• Object of type `int` with value 42

• Variable `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)

 ```a = 42 b = a ``` Both `a` and `b` refer to the same object: ```print(id(a)) print(id(b)) ``` ```140248719661832 140248719661832 ```

## Modifying An Integer In-Place? (Immutability)¶

```id(a)
```
```140248719661832
```
• 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
```
```140248719661864
```
```a = a + 7
id(a)         # <--- again, different object now
```
```140248719662088
```

## Immutability: Tuples¶

 ```a = (42, "xy", 13) b = a print(id(a)) print(id(b)) ``` ```140248434339648 140248434339648 ``` Like lists, but immutable No way to modify a tuple No appending No slice assignment No nothing
• And operator `+=`?

```a += ('foo', 'bar')
print(a)
print(id(a))
print(id(b))
```
```(42, 'xy', 13, 'foo', 'bar')
140248436164944
140248434339648
```
• ⟶ leaves `b` alone

```b
```
```(42, 'xy', 13)
```

## Mutability: Lists (1)¶

Lists are mutable

• Objects can be modified

• E.g. by using `append()`

 ```a = [1, 2, 3] b = a b ``` ```[1, 2, 3] ``` Both now refer to the same object Modify `b` … ```b.append(4) b ``` ```[1, 2, 3, 4] ``` … and see `a` modified! ```a ``` ```[1, 2, 3, 4] ```

## 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 reference

• `is`: 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
```