1
00:00:04,780 --> 00:00:07,430
Python's got some built-in functions

2
00:00:07,430 --> 00:00:09,309
that can be used as an alternative

3
00:00:09,309 --> 00:00:12,530
to comprehensions. Generally, I suggest using

4
00:00:12,530 --> 00:00:15,170
comprehensions instead, and in fact Guildo

5
00:00:15,170 --> 00:00:17,540
van Rossum wanted to remove map and

6
00:00:17,540 --> 00:00:20,180
filter from Python altogether, but was

7
00:00:20,180 --> 00:00:22,460
instead persuaded to keep them. Now you

8
00:00:22,460 --> 00:00:24,380
can find his reasoning about this at the

9
00:00:24,380 --> 00:00:25,580
link that I've got on the screen there

10
00:00:25,580 --> 00:00:27,770
now, and this link is in the resources

11
00:00:27,770 --> 00:00:29,539
section of the video. This is well worth

12
00:00:29,539 --> 00:00:30,890
a read, even if you're one of those

13
00:00:30,890 --> 00:00:33,440
Python programmers who like to use map.

14
00:00:33,440 --> 00:00:35,510
So we're going to take a look at these

15
00:00:35,510 --> 00:00:37,400
functions, because you need to be

16
00:00:37,400 --> 00:00:38,989
familiar with them in order to

17
00:00:38,989 --> 00:00:41,360
understand code that uses them. So we'll

18
00:00:41,360 --> 00:00:43,820
start with Map, and I'll use an earlier

19
00:00:43,820 --> 00:00:46,370
comprehension example from the course, so

20
00:00:46,370 --> 00:00:48,290
that we can see both methods producing

21
00:00:48,290 --> 00:00:50,900
the same results. We're going to swing

22
00:00:50,900 --> 00:00:52,699
over to IntelliJ and I'm going

23
00:00:52,699 --> 00:00:56,390
to create a new project. Make sure that I

24
00:00:56,390 --> 00:00:58,489
select the right project SDK which will

25
00:00:58,489 --> 00:01:01,760
be the latest version of Python, and I'm

26
00:01:01,760 --> 00:01:06,409
going to call this one map and I'll make

27
00:01:06,409 --> 00:01:07,460
sure I've got it in the right folder

28
00:01:07,460 --> 00:01:16,100
here, Finish, and then we'll create the

29
00:01:16,100 --> 00:01:19,659
actual project, the Python file, as well.

30
00:01:19,659 --> 00:01:21,979
I'm going to call that

31
00:01:21,979 --> 00:01:28,969
map_intro. Okay, then I'm going to paste

32
00:01:28,969 --> 00:01:31,009
this code, that I talked about from an earlier

33
00:01:31,009 --> 00:01:32,869
video in this course, to save a bit of

34
00:01:32,869 --> 00:01:35,840
time, and what I'll do is run the program

35
00:01:35,840 --> 00:01:37,340
to make sure that it actually works.

36
00:01:37,340 --> 00:01:41,359
So I right-click and select Run and you

37
00:01:41,359 --> 00:01:42,979
can see we've now got the results

38
00:01:42,979 --> 00:01:44,090
appearing at the bottom of the screen.

39
00:01:44,090 --> 00:01:46,219
Now this program is using two

40
00:01:46,219 --> 00:01:49,280
comprehensions. The first produces a list

41
00:01:49,280 --> 00:01:50,799
of all the characters in the text,

42
00:01:50,799 --> 00:01:53,659
capitalized. The second produces a list

43
00:01:53,659 --> 00:01:55,789
of all the words in the text, again

44
00:01:55,789 --> 00:01:58,310
capitalized. Alright, so we can do the

45
00:01:58,310 --> 00:02:01,280
same thing with the map function. So what

46
00:02:01,280 --> 00:02:02,299
I'll do is I'll put the corresponding

47
00:02:02,299 --> 00:02:04,909
map code after each one then we'll see

48
00:02:04,909 --> 00:02:06,770
what it's doing. So I come down

49
00:02:06,770 --> 00:02:10,850
here firstly and we'll just make a comment -

50
00:02:10,850 --> 00:02:12,319
the fact that we're using map here - so

51
00:02:12,319 --> 00:02:15,290
use map, and this will be map underscore

52
00:02:15,290 --> 00:02:16,040
capitals

53
00:02:16,040 --> 00:02:17,960
is equal to

54
00:02:17,960 --> 00:02:20,420
list left parentheses map left

55
00:02:20,420 --> 00:02:25,730
parentheses str dot upper comma space

56
00:02:25,730 --> 00:02:28,640
text and then closing off the two, 

57
00:02:28,640 --> 00:02:30,290
closing off by selecting the two right

58
00:02:30,290 --> 00:02:32,060
parentheses. Then we'll just print that

59
00:02:32,060 --> 00:02:36,020
out, map underscore capitals. We'll go down

60
00:02:36,020 --> 00:02:38,600
below the second comprehension and put

61
00:02:38,600 --> 00:02:41,690
some map equivalent code, so we'll put a comment

62
00:02:41,690 --> 00:02:43,760
there to that effect - map underscore

63
00:02:43,760 --> 00:02:46,970
words, this time, is equal to list left

64
00:02:46,970 --> 00:02:50,660
parentheses map left parentheses str

65
00:02:50,660 --> 00:02:54,310
dot upper comma space text dot split

66
00:02:54,310 --> 00:02:57,140
parentheses is going to be, two single

67
00:02:57,140 --> 00:02:58,820
quotes with a the space in between them,

68
00:02:58,820 --> 00:03:02,750
and the three closing right parentheses. Then

69
00:03:02,750 --> 00:03:04,280
we'll just print out at the value of

70
00:03:04,280 --> 00:03:07,820
map underscore words. So if we run the

71
00:03:07,820 --> 00:03:10,040
program again now, you can see there

72
00:03:10,040 --> 00:03:12,950
that we've got the identical output. So map

73
00:03:12,950 --> 00:03:15,320
takes two arguments. The first is a

74
00:03:15,320 --> 00:03:17,870
function and I've used the upper

75
00:03:17,870 --> 00:03:19,870
function from the string class str.

76
00:03:19,870 --> 00:03:22,490
Remember that when passing a function as

77
00:03:22,490 --> 00:03:24,410
an argument, you don't include the

78
00:03:24,410 --> 00:03:26,690
opening and closing parentheses. When you

79
00:03:26,690 --> 00:03:28,580
use parentheses you're passing the

80
00:03:28,580 --> 00:03:31,010
result of calling the function, but here

81
00:03:31,010 --> 00:03:32,570
we want to pass the function itself.

82
00:03:32,570 --> 00:03:35,150
The second argument's an iterator.

83
00:03:35,150 --> 00:03:36,650
You can use anything that can be

84
00:03:36,650 --> 00:03:38,810
iterated over, such as a string or a list.

85
00:03:38,810 --> 00:03:41,300
So map underscore capitals is using the

86
00:03:41,300 --> 00:03:44,210
string text and map iterates over each

87
00:03:44,210 --> 00:03:46,400
character in the string and calls the

88
00:03:46,400 --> 00:03:49,190
str dot upper function for each one. It

89
00:03:49,190 --> 00:03:51,410
then builds up another interable which we

90
00:03:51,410 --> 00:03:53,930
convert to a list. Map underscore words

91
00:03:53,930 --> 00:03:56,030
is doing the same thing but creates an

92
00:03:56,030 --> 00:03:58,220
interable by splitting the text into

93
00:03:58,220 --> 00:04:00,590
words. Split returns the list, remember,

94
00:04:00,590 --> 00:04:03,110
so the split list is an interable that

95
00:04:03,110 --> 00:04:05,060
map's iterating over, and that's

96
00:04:05,060 --> 00:04:07,130
basically what map does. It calls the

97
00:04:07,130 --> 00:04:09,590
function for each item in the interable

98
00:04:09,590 --> 00:04:12,380
and stores the result in a new interable.

99
00:04:12,380 --> 00:04:14,390
So we've used that interable to create a list,

100
00:04:14,390 --> 00:04:16,339
but we could have, instead, just iterated

101
00:04:16,339 --> 00:04:19,579
over it. So as an example there,

102
00:04:19,579 --> 00:04:23,270
we could type for x in map parentheses str

103
00:04:23,270 --> 00:04:28,150
dot upper comma text dot split,

104
00:04:28,150 --> 00:04:31,190
then in left and right parentheses, single

105
00:04:31,190 --> 00:04:33,259
quote and a space between, and the two

106
00:04:33,259 --> 00:04:35,449
closing right parentheses and a colon on

107
00:04:35,449 --> 00:04:37,130
the end there, so we iterate over

108
00:04:37,130 --> 00:04:41,020
each element, and then print and in parentheses, x.

109
00:04:41,020 --> 00:04:44,810
So if you run that, you can see that this

110
00:04:44,810 --> 00:04:47,210
is exactly the same map code, but instead

111
00:04:47,210 --> 00:04:49,639
of converting the interable to a list, we

112
00:04:49,639 --> 00:04:52,430
iterate over it and print each item.

113
00:04:52,430 --> 00:04:53,720
And you can see there that the output was

114
00:04:53,720 --> 00:04:56,750
the capitalized words from text. So is

115
00:04:56,750 --> 00:04:58,430
there anything to be gained from using

116
00:04:58,430 --> 00:05:00,380
map instead of a comprehension? In my

117
00:05:00,380 --> 00:05:02,449
opinion, I'd say there isn't.

118
00:05:02,449 --> 00:05:04,610
The comprehensions are easier to write

119
00:05:04,610 --> 00:05:07,669
and more importantly, easier to read. It's just

120
00:05:07,669 --> 00:05:09,409
more obvious what they're doing,

121
00:05:09,409 --> 00:05:11,720
which was Guido's main reason for wanting to

122
00:05:11,720 --> 00:05:14,990
remove map from Python 3. But what about

123
00:05:14,990 --> 00:05:17,150
performance? Well you now know how to

124
00:05:17,150 --> 00:05:19,639
test that performance yourself. However,

125
00:05:19,639 --> 00:05:21,740
there are ways to make timing functions

126
00:05:21,740 --> 00:05:24,080
even easier, and it may not have been

127
00:05:24,080 --> 00:05:26,210
obvious from the earlier video. It's a

128
00:05:26,210 --> 00:05:27,710
technique I'm going to rely on in the

129
00:05:27,710 --> 00:05:29,569
next few videos, and I'll take the

130
00:05:29,569 --> 00:05:31,699
opportunity to introduce it and explain

131
00:05:31,699 --> 00:05:35,509
it here. So it's now challenge time.

132
00:05:35,509 --> 00:05:37,070
So the challenge is to wrap each of the

133
00:05:37,070 --> 00:05:39,199
four blocks of code in function

134
00:05:39,199 --> 00:05:41,599
definitions then use the timeit module

135
00:05:41,599 --> 00:05:44,719
to time each one. Remember to import timeit

136
00:05:44,719 --> 00:05:47,240
at the start of the file. Now my

137
00:05:47,240 --> 00:05:48,740
solution will use a slightly different

138
00:05:48,740 --> 00:05:51,830
approach, to save time in the video. The

139
00:05:51,830 --> 00:05:53,150
test of whether your solution works,

140
00:05:53,150 --> 00:05:55,460
though, is if it successfully times all

141
00:05:55,460 --> 00:05:57,650
four approaches to capitalizing the

142
00:05:57,650 --> 00:05:59,990
characters and words in text. Alright

143
00:05:59,990 --> 00:06:01,490
so that's the challenge. Pause the video

144
00:06:01,490 --> 00:06:03,229
and see how you go with it, and when

145
00:06:03,229 --> 00:06:04,490
you're ready come back and you can view

146
00:06:04,490 --> 00:06:07,999
my solution. So pause the video now.

147
00:06:07,999 --> 00:06:10,039
Alright, so welcome back. Let's go

148
00:06:10,039 --> 00:06:11,839
through the solution to the challenge,

149
00:06:11,839 --> 00:06:14,779
step by step. So the first step is

150
00:06:14,779 --> 00:06:17,059
to include each code block in a function

151
00:06:17,059 --> 00:06:19,639
definition, so let's do that. So starting

152
00:06:19,639 --> 00:06:21,889
at the top here, on line 3, we're going to

153
00:06:21,889 --> 00:06:23,389
make that a function. I'm going to add a

154
00:06:23,389 --> 00:06:26,829
line, def space comp underscore caps

155
00:06:26,829 --> 00:06:29,019
parentheses colon

156
00:06:29,019 --> 00:06:32,239
and then we'll indent the code, the next

157
00:06:32,239 --> 00:06:34,669
two lines, and we'll change the print to

158
00:06:34,669 --> 00:06:39,860
a return capitals. That's the first one,

159
00:06:39,860 --> 00:06:41,889
and we need to make sure that we're

160
00:06:41,889 --> 00:06:43,939
spacing this out correctly. We need two

161
00:06:43,939 --> 00:06:48,559
lines, like so, to avoid those warnings or

162
00:06:48,559 --> 00:06:50,419
to get rid of those warnings. Next we

163
00:06:50,419 --> 00:06:52,459
want to create the map underscore caps

164
00:06:52,459 --> 00:06:54,739
function, so def space map underscore

165
00:06:54,739 --> 00:06:57,769
caps parentheses colon. We'll indent these

166
00:06:57,769 --> 00:07:00,169
two lines again, converting the second

167
00:07:00,169 --> 00:07:04,459
line, instead of a print to a return,

168
00:07:04,459 --> 00:07:06,409
and remembering to add two spaces or two

169
00:07:06,409 --> 00:07:08,419
lines between the end of the function and

170
00:07:08,419 --> 00:07:10,429
the start of the next one. Next one we're

171
00:07:10,429 --> 00:07:13,489
going to call def comp underscore words

172
00:07:13,489 --> 00:07:16,039
because it's a comprehension version, so

173
00:07:16,039 --> 00:07:17,659
comp underscore words parentheses

174
00:07:17,659 --> 00:07:28,819
colon, indent again and return words. Okay,

175
00:07:28,819 --> 00:07:30,800
and then the fourth one, making sure

176
00:07:30,800 --> 00:07:32,449
we've got two lines there separating it,

177
00:07:32,449 --> 00:07:34,849
and it's going to be def map underscore

178
00:07:34,849 --> 00:07:38,029
words parentheses colon.

179
00:07:38,029 --> 00:07:40,369
We'll indent these two lines, and this time we

180
00:07:40,369 --> 00:07:43,309
want to change the variable name here, to

181
00:07:43,309 --> 00:07:45,469
avoid any problems. I'm going to call

182
00:07:45,469 --> 00:07:48,319
that map underscore x instead, or map

183
00:07:48,319 --> 00:07:50,149
underscore w it should say, for map

184
00:07:50,149 --> 00:07:51,979
underscore words, and then we're going to

185
00:07:51,979 --> 00:07:56,089
return on the next line, map underscore w.

186
00:07:56,089 --> 00:07:59,569
And then ww want a two line space there.

187
00:07:59,569 --> 00:08:01,129
Well actually, what we can do now

188
00:08:01,129 --> 00:08:03,589
is delete that, because you no longer need

189
00:08:03,589 --> 00:08:06,679
that other code. Before attempting to time

190
00:08:06,679 --> 00:08:08,059
the function, we should really call each

191
00:08:08,059 --> 00:08:09,259
one just to make sure that it still

192
00:08:09,259 --> 00:08:11,479
works. So let's do that. So I'm going to add

193
00:08:11,479 --> 00:08:15,169
if on line 26, underscore underscore name

194
00:08:15,169 --> 00:08:19,009
underscore underscore equals equals single quotes

195
00:08:19,009 --> 00:08:20,940
underscore main underscore

196
00:08:20,940 --> 00:08:22,890
underscore so, we've done that a

197
00:08:22,890 --> 00:08:25,860
number of times now, a colon, and let's print them

198
00:08:25,860 --> 00:08:27,840
out. So print comp underscore caps, the first

199
00:08:27,840 --> 00:08:31,170
function, results, second one, print map

200
00:08:31,170 --> 00:08:32,750
underscore caps,

201
00:08:32,750 --> 00:08:35,400
third one print, it's going to be

202
00:08:35,400 --> 00:08:38,820
comp underscore words and the fourth

203
00:08:38,820 --> 00:08:43,820
one, print map underscore words. Okay.

204
00:08:43,820 --> 00:08:45,900
Let's run the program to make sure

205
00:08:45,900 --> 00:08:49,170
it works, and you can see that it's working

206
00:08:49,170 --> 00:08:51,420
nicely. Alright so let's finish the video

207
00:08:51,420 --> 00:08:53,280
here. In the next one, we'll move on

208
00:08:53,280 --> 00:08:55,890
and we'll start timing the call to these

209
00:08:55,890 --> 00:08:57,630
functions. So I'll see you in the next

210
00:08:57,630 --> 00:08:59,870
video.

