1
00:00:05,200 --> 00:00:09,520
Alright, so how did you get on with the challenge?
It gave you a chance to practise iterating over

2
00:00:09,520 --> 00:00:15,913
a dictionary, and adding items to one. Now I've
called my Python file simple_deepcopy, 

3
00:00:15,913 --> 00:00:19,600
and I've already copied the sample
code I showed at the end of the last video.

4
00:00:19,600 --> 00:00:25,120
So to copy the dictionary, we need to start
by creating a new dictionary. Alright, so I'm

5
00:00:25,120 --> 00:00:31,280
going to remove this line 14, line 13 rather,
and replace that with new_dict

6
00:00:31,280 --> 00:00:36,400
is equal to, and we want an empty dictionary, so
left and right curly braces. Next we need to

7
00:00:36,400 --> 00:00:43,680
iterate over the keys and values of the original
dictionary. So I'm going to type for key comma value

8
00:00:43,680 --> 00:00:52,560
in d dot items, parentheses colon. The challenge
description stated that our code only has to cope

9
00:00:52,560 --> 00:00:58,025
with values that are lists or dictionaries. This means
we can use their copy method to create a copy

10
00:00:58,025 --> 00:01:07,328
of the value. So I'm going to type new_value
is equal to value.copy, parentheses there,

11
00:01:07,328 --> 00:01:12,419
and we finish by adding the new value to the
new dictionary. We use the key that it had in the original. 

12
00:01:12,419 --> 00:01:19,040
So I'm going to type new_dict square
brackets, key in square brackets, equals

13
00:01:19,040 --> 00:01:23,840
new_value. Alright, and when the loop
finishes, all the values will have been copied 

14
00:01:23,840 --> 00:01:30,812
and added to the new dictionary. All that remains to do,
is to return the new dictionary, so let's do that.

15
00:01:30,812 --> 00:01:39,280
On line 18, I'm going to type return new_dict. Alright.
So on line 22, we change the amount of ginger

16
00:01:39,280 --> 00:01:44,560
that we have in the copied dictionary. Because we
copied the inner dictionaries, the original value

17
00:01:44,560 --> 00:01:53,200
should remain unchanged. Now if we have a quick
look at the recipe's dictionary in contents.py,

18
00:01:53,200 --> 00:02:00,277
down here, we can see that butter chicken needs
three gingers. So back in simple_deepcopy again,

19
00:02:00,277 --> 00:02:07,200
line 24 should hopefully print three.
Let's run the program now, and a space there to

20
00:02:07,200 --> 00:02:14,064
keep IntelliJ happy. We'll run it again. We confirm
that the copy now has the value of 300 for ginger,

21
00:02:14,064 --> 00:02:19,680
but the original value is unchanged. Alright, so
that's the challenge completed. We deliberately

22
00:02:19,680 --> 00:02:25,280
restricted what your code had to do to complete
the challenge, because this isn't a full deep copy.

23
00:02:25,280 --> 00:02:30,480
It only creates a copy of dictionaries and lists
that are values. If they also contain dictionaries

24
00:02:30,480 --> 00:02:36,635
or lists, a shallow copy will be performed on those
inner objects. An example is better than words here,

25
00:02:36,635 --> 00:02:45,605
so let's actually create a new Python file. So
I'm going to call mine deep copy is recursive -

26
00:02:45,605 --> 00:02:53,244
deepcopy_is_recursive.
I'm going to import our my_deepcopy function

27
00:02:53,244 --> 00:02:59,440
and the copy module. So I'm
going to do from simple_deepcopy

28
00:02:59,440 --> 00:03:06,160
import my_deepcopy. On the next line, import
copy. Alright, so we need a dictionary to copy

29
00:03:06,160 --> 00:03:11,520
and I'm going to keep it very simple.
So I'm going to paste this in, line four.

30
00:03:11,520 --> 00:03:14,900
So I kept the dictionary list small to
make it easy to see what's going on.

31
00:03:14,900 --> 00:03:21,253
Let's continue on. I'm gonna type copy
underscore 1 equals copy.deepcopy

32
00:03:21,253 --> 00:03:30,000
original. And on the next line, copy underscore
two equals my_deepcopy original.

33
00:03:30,000 --> 00:03:40,720
Then line 12, print original, then we'll also
print copy 1. We'll do the same - print copy 2.

34
00:03:40,720 --> 00:03:45,040
Alright, and again, so I've kept the dictionary
and the list small, just to make it easy to

35
00:03:45,040 --> 00:03:50,960
see what's going on. So on line 9, we use the deep
copy function to copy the original dictionary.

36
00:03:50,960 --> 00:03:55,585
Line 10 uses the my_deepcopy
function from the challenge.

37
00:03:55,600 --> 00:03:59,840
So let's run the program
and see what the results are.

38
00:04:04,000 --> 00:04:09,120
And you can see there, all three dictionaries look
the same. So ignore the first two lines of output.

39
00:04:09,120 --> 00:04:13,520
They're produced because we imported simple
underscore deepcopy. You'll learn all about

40
00:04:13,520 --> 00:04:19,360
that when we talk about importing, later in the
course. The value for Tim, on line five, is a list

41
00:04:19,360 --> 00:04:24,800
containing my surname and a list of jobs. To check
that our two copies contain copies of these lists,

42
00:04:24,800 --> 00:04:31,680
I'll append the country for Tim, and also
for Jean-Paul. So we'll come down here,

43
00:04:31,680 --> 00:04:39,360
line 12. We're going to type original square
brackets, Tim in double quotes, dot append.

44
00:04:39,360 --> 00:04:44,240
In parentheses, double quotes Australia,
and for Jean-Paul I'm going to type

45
00:04:44,240 --> 00:04:54,880
original square brackets double quotes J-P
dot append parentheses double quotes UK.

46
00:04:54,880 --> 00:04:58,000
Now if we run this,

47
00:04:58,000 --> 00:05:03,030
we can see in the case of the first copy,
we can see that at the top, the first one,

48
00:05:03,030 --> 00:05:08,800
has got both the countries, but the countries don't
get added to the lists in our copies - the second

49
00:05:08,800 --> 00:05:14,160
and third lines. To see the difference between our
function, and the copy module's deepcopy function,

50
00:05:14,160 --> 00:05:18,960
what I'm going to do is mutate the inner lists
in the original. Now I'm referring to the inner

51
00:05:18,960 --> 00:05:25,200
lists that contain Programmer and Teacher,
back up here on lines 5 and 6. Jean-Paul

52
00:05:25,200 --> 00:05:30,160
worked as a motorcycle courier for a while,
and I was a cashier in an amusement arcade,

53
00:05:30,160 --> 00:05:34,925
so I'm going to append those jobs to the inner
lists. Let's go ahead and do that. Come down here,

54
00:05:34,925 --> 00:05:41,040
after the country additions there, and I'm going to
type original, square brackets double quotes, Tim 

55
00:05:41,040 --> 00:05:50,480
in those double quotes. Then another double quotes and
1 dot append parentheses double quotes cashier.

56
00:05:50,480 --> 00:05:55,840
Then on the next line I'm going to type
jp_list equals original

57
00:05:55,840 --> 00:06:02,640
square brackets double quotes J-P. On the
next line, jp_list then 1

58
00:06:02,640 --> 00:06:08,103
in square brackets, dot append
parenthesis double quotes Courier,

59
00:06:09,440 --> 00:06:16,878
like so. So what I've done there, is I've made
the change in two different ways. So on line 15,

60
00:06:16,878 --> 00:06:20,880
the code refers to the second item for the
value of Tim. So I'll just scroll up so we can

61
00:06:20,880 --> 00:06:25,440
see the original there as well. So I've made
the change in two different ways. On line 15,

62
00:06:25,440 --> 00:06:31,200
the code refers to the second item in the value
for Tim. The value is a list, and the second item

63
00:06:31,200 --> 00:06:36,850
in that list is another list, which contains
Programmer and Teacher. That's on line five.

64
00:06:36,850 --> 00:06:43,619
We append cashier to that inner list on line 15.
Lines 16 and 17 do the same thing - jp_list 

65
00:06:43,619 --> 00:06:49,760
is bound to the value for jp. jp_list 1 in
square brackets is the second item in that list.

66
00:06:49,760 --> 00:06:55,520
I'll split the code up into two steps, in case
you're unsure about the indexing on line 15.

67
00:06:55,520 --> 00:07:01,280
In both cases, we append a new job to the inner list.
If you find those indices on line 15 confusing,

68
00:07:01,280 --> 00:07:06,560
review the lectures in the list and tuple section,
starting with nested tuples and lists. 

69
00:07:06,560 --> 00:07:12,160
Alright, so let's run the program to check the output. So we
get the new jobs added to the list in the original

70
00:07:12,160 --> 00:07:21,280
dictionary. We can scroll over and see that; Cashier
for me and Courier for Jean-Paul. Now the second

71
00:07:21,280 --> 00:07:27,680
dictionary in the output doesn't contain the
new jobs. You can see that there, in both cases.

72
00:07:27,680 --> 00:07:33,709
We use the copy module's deepcopy function to
create copy_1. We can see that on line9,

73
00:07:33,709 --> 00:07:39,840
and that performs a deep copy of all contained
objects. Our my_deepcopy function

74
00:07:39,840 --> 00:07:45,680
only goes one level down. We use the copy method
in the function, and that performs a shallow copy.

75
00:07:45,680 --> 00:07:54,387
As a result, the inner list in copy_2
is a reference to the same inner list in original.

76
00:07:54,387 --> 00:07:59,600
The deepcopy function uses a technique
called recursion. When it finds an object

77
00:07:59,600 --> 00:08:05,280
that can contain other objects, it calls
itself again to copy those containers.

78
00:08:05,280 --> 00:08:09,840
If we wanted to write a complete deep copy
function, you'd need to use recursion. 

79
00:08:09,840 --> 00:08:15,200
We'll cover recursion a bit later in the course, when we
revisit functions. Alright, so that's the end of

80
00:08:15,200 --> 00:08:20,960
the practical use of dictionaries. In the next few
lectures, we're going to be looking at the theory.

81
00:08:20,960 --> 00:08:26,720
A dictionary can contain millions of keys,
but retrieving a value for a key is very fast.

82
00:08:26,720 --> 00:08:31,200
We'll look at the theory of how that works, using
something called hashes. We saw them mentioned in

83
00:08:31,200 --> 00:08:38,640
the documentation, earlier - now it's time to find
out what they are. See you in the next video.

