1
00:00:05,280 --> 00:00:10,240
I'll finish our discussion of deep and shallow
copies with a quick example. We'll perform a deep

2
00:00:10,240 --> 00:00:15,040
copy of our dictionary and examine the difference.
What we need to do is open up our earlier

3
00:00:15,040 --> 00:00:21,920
shallow_copy program, and we're going
to change this to be using a deep copy instead.

4
00:00:21,920 --> 00:00:27,678
First though, a quick review. We'll run the
program, then we'll check the output.

5
00:00:27,678 --> 00:00:34,378
On line 14, we use the reference to the teddy list
in the things dictionary. We append toy to the list.

6
00:00:34,378 --> 00:00:39,237
The last two lines of the output are the same -
the toy entry appears in both lines of output.

7
00:00:39,237 --> 00:00:42,960
Now this should no longer be surprising.
The value in both dictionaries

8
00:00:42,960 --> 00:00:48,480
are referring to the same list. Now let's have
a look at a deep copy. As you've seen 

9
00:00:48,480 --> 00:00:54,720
from the documentation that I linked to, in the last video,
the copy module provides a deep copy function.

10
00:00:54,720 --> 00:01:01,156
To use the function, we need to import
it into our program. Going up to line one,

11
00:01:02,640 --> 00:01:07,840
import copy. We'll be looking at importing
in more detail, because there are different

12
00:01:07,840 --> 00:01:13,027
ways to import things, but at the moment
we're focusing on dictionaries and copying.

13
00:01:13,027 --> 00:01:17,520
The import's very similar to when we imported the
random module, back in the Program Flow Control and

14
00:01:17,520 --> 00:01:23,040
Python section. That was in the video The Random
Module and Import. So review that video, 

15
00:01:23,040 --> 00:01:27,120
if you want to remind yourself what's happening here. 
Alright, so let's see what happens when we perform

16
00:01:27,120 --> 00:01:32,080
a deep copy, rather than a shallow copy. So I'm
going to add some comments to the code, comment

17
00:01:32,080 --> 00:01:38,160
out something and then use the deep copy function.
I'm going to come down here and comment out line 9.

18
00:01:38,160 --> 00:01:45,920
Line 8, which will become line 9, I'm
going to comment Perform a shallow copy,

19
00:01:45,920 --> 00:01:53,802
because that's obviously what that was doing.
And down here, comment Perform a deep copy. 

20
00:01:53,802 --> 00:02:02,472
Then the actual code will be things equals copy
dot deepcopy, and in parentheses, animals.

21
00:02:03,200 --> 00:02:08,767
So this time when I run this, we can see that toy
is only added to the list in the things dictionary.

22
00:02:08,767 --> 00:02:15,064
Each dictionary now contains its own copy of the
lists. When we append to the list in things, on line 20,

23
00:02:15,064 --> 00:02:18,880
it's got no effect on the list in animals - we
can see that with the output. So it might actually

24
00:02:18,880 --> 00:02:25,864
help to confirm that, by printing out the ids of
the list. Alright, so I'm going to copy that part of the printout.

25
00:02:25,864 --> 00:02:30,434
I'm going to add something at the start:
id parentheses, paste that in, and put a

26
00:02:30,480 --> 00:02:34,960
comma outside of the right parentheses and do the
same for the next line as well. So we're printing

27
00:02:34,960 --> 00:02:46,735
out the id as well as the actual values. So id
parentheses, paste it in, and a comma. We'll run this

28
00:02:47,120 --> 00:02:51,520
So the first two lines of output,
produced by lines 15 and 16,

29
00:02:51,520 --> 00:02:55,760
show that the lists have different ids. They're
not the same list, and it's not surprising

30
00:02:55,760 --> 00:03:01,760
that toy isn't added to both lists.
Now if we swap the commenting around,

31
00:03:01,760 --> 00:03:09,680
by uncommenting line 10 and commenting out line
13, we'll go back to performing a shallow copy.

32
00:03:09,680 --> 00:03:17,600
We run this. This time you can see the ids are the
same. Both dictionaries contain references to the

33
00:03:17,600 --> 00:03:24,240
same lists. Because there's only one list, we get
toy appearing in both the last two lines of output.

34
00:03:24,240 --> 00:03:28,287
Okay, so that's the difference
between deep and shallow copies.

35
00:03:28,287 --> 00:03:33,259
A deep copy will also copy any objects that
are contained in whatever you're copying.

36
00:03:33,259 --> 00:03:39,360
A shallow copy only copies references - it doesn't
make copies of contained objects. I'm going to

37
00:03:39,360 --> 00:03:43,040
finish our discussion of dictionaries with
some theory. We'll look at how dictionaries

38
00:03:43,040 --> 00:03:50,917
manage to be so fast when retrieving items using
a key. But before then, it's time for a challenge.

39
00:03:51,600 --> 00:03:55,613
Your challenge is to write a function
that takes the dictionary as an argument,

40
00:03:55,613 --> 00:04:00,640
and returns a deep copy of the dictionary. You're
going to write your own function, to do a similar

41
00:04:00,640 --> 00:04:06,720
job to the deepcopy function that we've just used,
but you'll do it without using the copy module.

42
00:04:06,720 --> 00:04:10,800
Your function will be a lot simpler than
deepcopy. It only has to cope with 

43
00:04:10,800 --> 00:04:16,399
one level of contained objects. It should be able to
successfully copy dictionaries like our animals

44
00:04:16,399 --> 00:04:20,320
or recipes dictionaries. It doesn't
have to handle dictionaries

45
00:04:20,320 --> 00:04:25,892
that contain objects that also contain objects.
That's much too difficult at this stage.

46
00:04:26,960 --> 00:04:31,040
The basic approach will be to
create a new empty dictionary.

47
00:04:31,040 --> 00:04:35,380
Next, iterate over the keys and values
of the dictionary that's being copied.

48
00:04:35,380 --> 00:04:41,040
For each key, copy the value, then add the copy of
the value to the new dictionary. Your function 

49
00:04:41,040 --> 00:04:47,021
only has to handle values that are dictionaries or
lists. Both of those objects have a copy method.

50
00:04:48,400 --> 00:04:53,008
The code to test your function might look
something like you can see on screen here,

51
00:04:53,008 --> 00:04:55,840
so pause the video if you want to look at that.

52
00:05:00,160 --> 00:05:03,422
And this is the output you should get.

53
00:05:04,400 --> 00:05:06,720
Alright, so that's the challenge,
see how you go with it, 

54
00:05:06,720 --> 00:05:09,840
and I'll go over my solution to it in the next video.

