# Shallow copy vs deep copy

The difference between shallow and deep copying is **only relevant for compound objects** (objects that contain other objects, like lists or class instances):

* **Shallow copy**: constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. Ie. uou have a new outer list, but inner lists are references.
* **Deep copy**: constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original. Copies the nested lists also, so it is a recursive copy.
* **Assignment**: does not copy. It simply sets the reference to the old data.

Example:

```python
import copy

a = [1, 2, 3]
b = [4, 5, 6]
c = [a, b]
```

Using **normal assignment** operatings to copy:

```python
d = c

print id(c) == id(d)          # True - d is the same object as c
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]
```

Using a **shallow copy**:

```python
d = copy.copy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]
```

Using a **deep copy**:

```
d = copy.deepcopy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # False - d[0] is now a new object
```
