1 00:00:07,930 --> 00:00:10,385 Glad to have you back. 2 00:00:10,385 --> 00:00:14,669 Here's a little way of the programmer advice on when to use a Lambda expression, 3 00:00:14,669 --> 00:00:19,575 and when to use a named function for your key parameter when sorting. 4 00:00:19,575 --> 00:00:27,720 Basically, my rule of thumb is if the lambda expression is short and simple, 5 00:00:27,720 --> 00:00:31,065 so that it's pretty easy to understand what it's doing, 6 00:00:31,065 --> 00:00:32,940 use the lambda expression, 7 00:00:32,940 --> 00:00:35,580 and as soon as it gets too complex, 8 00:00:35,580 --> 00:00:37,590 refer to a name function instead, 9 00:00:37,590 --> 00:00:41,865 and give it a good name that describes the property you're trying to sort by. 10 00:00:41,865 --> 00:00:44,720 For example, here's one that's just at 11 00:00:44,720 --> 00:00:49,750 the outer limits of what I'd consider simple enough to put it in a lambda expression. 12 00:00:49,750 --> 00:00:53,440 We have a dictionary called States. 13 00:00:55,220 --> 00:00:58,839 It's got as its keys, 14 00:00:58,970 --> 00:01:03,600 the names of states in the United States, Minnesota, Michigan, 15 00:01:03,600 --> 00:01:07,480 and Washington, and the value associated with each state, 16 00:01:07,480 --> 00:01:11,160 with each key is a list, 17 00:01:11,160 --> 00:01:13,395 a list of city names. 18 00:01:13,395 --> 00:01:15,390 St. Paul, Minneapolis, St. 19 00:01:15,390 --> 00:01:17,309 Cloud, Stillwater for Minnesota, 20 00:01:17,309 --> 00:01:18,570 Ann Arbor, Traverse City, 21 00:01:18,570 --> 00:01:20,710 and so on for Michigan. 22 00:01:20,860 --> 00:01:27,635 We want to sort the keys based on some property of their values. 23 00:01:27,635 --> 00:01:31,610 So, we have a generic structure where we have a dictionary 24 00:01:31,610 --> 00:01:35,835 called states and we're going to sort its keys. 25 00:01:35,835 --> 00:01:38,300 We just asked to sort the dictionary, 26 00:01:38,300 --> 00:01:41,090 but that always means we'll get to sort the keys, 27 00:01:41,090 --> 00:01:45,325 and our key function is going to take 28 00:01:45,325 --> 00:01:54,675 one item from that list as an input and it's going to look up some property, 29 00:01:54,675 --> 00:02:00,930 in fact it's going to look up that state in the states dictionary. 30 00:02:00,930 --> 00:02:04,580 But in this case, we're not just trying to get 31 00:02:04,580 --> 00:02:09,110 the whole list as the value associated with Minnesota, 32 00:02:09,110 --> 00:02:14,750 we're trying to get some property of that list and in this case, 33 00:02:14,750 --> 00:02:21,125 we're taking square of bracket zero, 34 00:02:21,125 --> 00:02:23,825 so that would get us St. Paul, 35 00:02:23,825 --> 00:02:26,240 and we're passing it to the len function, 36 00:02:26,240 --> 00:02:30,190 so that's going to give us eight. 37 00:02:31,310 --> 00:02:38,030 For Michigan, we would take the lists that states square bracket state, 38 00:02:38,030 --> 00:02:40,025 gets us the whole list of cities, 39 00:02:40,025 --> 00:02:42,575 we take square bracket zero from that, 40 00:02:42,575 --> 00:02:44,765 that'll get us to the city of Ann Arbor, 41 00:02:44,765 --> 00:02:47,045 and we'll pass that to the len function, 42 00:02:47,045 --> 00:02:48,990 so we'll get one, 43 00:02:48,990 --> 00:02:50,040 two, three, four, five, 44 00:02:50,040 --> 00:02:52,050 six, seven, eight, nine, 45 00:02:52,050 --> 00:02:54,225 Ann Arbor has nine letters, 46 00:02:54,225 --> 00:02:55,830 and similarly for Washington, 47 00:02:55,830 --> 00:02:57,585 we'll get the length of Seattle, 48 00:02:57,585 --> 00:03:00,555 which is seven letters. 49 00:03:00,555 --> 00:03:02,655 So, when we sort this, 50 00:03:02,655 --> 00:03:04,875 we should get a list of the states, 51 00:03:04,875 --> 00:03:06,794 Minnesota, Michigan, and Washington, 52 00:03:06,794 --> 00:03:09,710 but we should get them in the order, Washington first, 53 00:03:09,710 --> 00:03:14,280 because it's first city has a shorter name. 54 00:03:16,990 --> 00:03:26,770 Sure enough, we get Washington and then Minnesota, and then Michigan. 55 00:03:29,060 --> 00:03:35,540 So, that's great when the property we wanted with the length of the first city name, 56 00:03:35,540 --> 00:03:38,240 and as I said, I think this is sort of just at 57 00:03:38,240 --> 00:03:42,900 the outer limits of what's understandable in a Lambda expression. 58 00:03:42,900 --> 00:03:45,914 This got to be complicated, 59 00:03:45,914 --> 00:03:50,040 it worked pretty well to understand it because states square bracket state, 60 00:03:50,040 --> 00:03:51,740 and sort of chunk, 61 00:03:51,740 --> 00:03:53,750 a pattern that we've seen before, 62 00:03:53,750 --> 00:03:58,000 we're taking a dictionary key and we're looking up its value in the dictionary. 63 00:03:58,000 --> 00:04:01,020 If you think of that as a little chunk as 64 00:04:01,020 --> 00:04:03,880 that's the value of the state in the dictionary, 65 00:04:03,880 --> 00:04:06,605 then we can just parse this square bracket zero to say, "Oh, 66 00:04:06,605 --> 00:04:11,375 take the first element of the list and pass that to the len function." 67 00:04:11,375 --> 00:04:13,850 Anything much more complicated than this, 68 00:04:13,850 --> 00:04:18,610 I think would be pretty hard to read as a Lambda expression. 69 00:04:18,610 --> 00:04:22,310 Well, let's think about one of those harder things. 70 00:04:22,310 --> 00:04:26,480 Suppose that we wanted to take a different property. 71 00:04:26,480 --> 00:04:32,300 For each state, we want to find the number of cities in its city list that begin with 72 00:04:32,300 --> 00:04:39,660 the letter S. We want to sort in that order. 73 00:04:39,660 --> 00:04:42,420 So, okay. 74 00:04:42,420 --> 00:04:44,565 What does that property sound like? 75 00:04:44,565 --> 00:04:48,470 The number of states that begin with the letter S. Number of states, 76 00:04:48,470 --> 00:04:51,575 that sounds like it's going to be a count accumulation, 77 00:04:51,575 --> 00:04:54,130 and only those that begin with the letter S, 78 00:04:54,130 --> 00:04:56,555 that sounds like we're going to need to filter as we count. 79 00:04:56,555 --> 00:04:58,925 So, once a count and filter accumulation, 80 00:04:58,925 --> 00:05:01,985 it's not too hard to write it as a function, 81 00:05:01,985 --> 00:05:06,955 but it would be pretty hard to write just as a lambda expression. 82 00:05:06,955 --> 00:05:11,264 So, I'm going to write a function, 83 00:05:11,264 --> 00:05:14,785 I'm going to call it s_cities_count, 84 00:05:14,785 --> 00:05:19,550 and it's going to take as an input a city's list, 85 00:05:19,550 --> 00:05:26,330 and what it's going to produce as an output is a count of 86 00:05:26,330 --> 00:05:33,180 how many cities begin with a capital S. Well, 87 00:05:33,180 --> 00:05:35,310 this is a count filter and accumulation, 88 00:05:35,310 --> 00:05:42,550 so I'm going to say count equals zero for city in city's list, 89 00:05:43,550 --> 00:05:50,250 if the first letter of city is 90 00:05:50,250 --> 00:05:57,970 S then increment our counter by one. 91 00:05:58,550 --> 00:06:01,320 When we finish the iteration, 92 00:06:01,320 --> 00:06:05,900 ct will have the total number of cities that began with S, 93 00:06:06,000 --> 00:06:11,460 so we'll return ct. Now, 94 00:06:11,460 --> 00:06:13,575 how am I going to use that? 95 00:06:13,575 --> 00:06:17,960 The key function is going to take one state as input, 96 00:06:17,960 --> 00:06:23,825 and I wrote this city's count to do our accumulation as I was taking a city's list. 97 00:06:23,825 --> 00:06:28,680 So, I can't just say key equals as cities count. 98 00:06:28,730 --> 00:06:35,795 That's not going to work because the key function has to take one state as an input, 99 00:06:35,795 --> 00:06:39,530 and my key function is taking a list of cities as an input. 100 00:06:39,530 --> 00:06:42,905 So, this is going to be a little bit of a hybrid. 101 00:06:42,905 --> 00:06:49,935 I'm going to take one state as an input, 102 00:06:49,935 --> 00:06:53,440 I'm going to look it up to get the city's list. 103 00:06:55,760 --> 00:07:01,285 That's sort of our canonical way of sorting a dictionary by its values, 104 00:07:01,285 --> 00:07:07,355 is we look up the key state in the states dictionary, 105 00:07:07,355 --> 00:07:09,300 but that's going to give me a city's list, 106 00:07:09,300 --> 00:07:13,840 and I'm going to pass that to my new function. 107 00:07:17,480 --> 00:07:20,370 Let's see, when you write that much code, 108 00:07:20,370 --> 00:07:22,930 the chances of running without an error aren't very good, 109 00:07:22,930 --> 00:07:24,510 let's see if I happened to get lucky. 110 00:07:24,510 --> 00:07:26,545 Wow, I did, okay. 111 00:07:26,545 --> 00:07:30,500 So, we got Michigan first and then Washington and then Minnesota. 112 00:07:30,500 --> 00:07:34,130 So hopefully, if we go look at the city's list, 113 00:07:34,130 --> 00:07:38,270 we'll see that Minnesota is the one that has a lot of cities beginning with S, 114 00:07:38,270 --> 00:07:40,750 and sure enough it does. 115 00:07:40,750 --> 00:07:45,270 Washington has St. Paul for one, St. 116 00:07:45,270 --> 00:07:48,030 Cloud for two, and Stillwater for three, 117 00:07:48,030 --> 00:07:50,865 so it had three. 118 00:07:50,865 --> 00:07:57,030 Washington had Seattle for just one and Michigan had zero. 119 00:07:57,030 --> 00:08:01,310 So, sure enough we got these in order of the number of 120 00:08:01,310 --> 00:08:05,640 cities that begin with the letter S. So, 121 00:08:05,640 --> 00:08:07,590 let's review what we did here again. 122 00:08:07,590 --> 00:08:09,780 We made a helper function, 123 00:08:09,780 --> 00:08:12,390 the name function called cities_count that did our thing, 124 00:08:12,390 --> 00:08:15,859 that was a little too complicated to put into the lambda expression, 125 00:08:15,859 --> 00:08:21,855 and we passed some property of our key, 126 00:08:21,855 --> 00:08:24,970 the list of cities in that state, 127 00:08:24,970 --> 00:08:30,630 we pass that as an input to this helper function s_cities_count. 128 00:08:31,040 --> 00:08:35,180 Now, it's actually possible to not use 129 00:08:35,180 --> 00:08:38,720 a lambda expression here at all and just refer to a named function, 130 00:08:38,720 --> 00:08:42,320 but we would have to make our function then, take as input, 131 00:08:42,320 --> 00:08:44,420 not the city's list, 132 00:08:44,420 --> 00:08:47,215 but the state name. 133 00:08:47,215 --> 00:08:50,120 So, I'm going to do a version of that I'm going 134 00:08:50,120 --> 00:08:59,010 to call it s_cities_count_for_state, 135 00:08:59,380 --> 00:09:05,270 and it's going to take a state name as its input and 136 00:09:05,270 --> 00:09:14,895 it'll make the cities' list equal to lookup of the state, 137 00:09:14,895 --> 00:09:16,875 in the States dictionary, 138 00:09:16,875 --> 00:09:21,380 and then everything else can be the same as before. 139 00:09:26,730 --> 00:09:30,390 If I do that, I can say that 140 00:09:30,390 --> 00:09:38,700 my key function is 141 00:09:38,700 --> 00:09:43,480 just as cities count for state. 142 00:09:46,090 --> 00:09:49,500 That time I wasn't so lucky. 143 00:09:50,180 --> 00:09:53,250 So, this is always instructive, 144 00:09:53,250 --> 00:09:54,420 let's look at this error message, 145 00:09:54,420 --> 00:09:58,795 it says syntax error EOF in multi-line statement on line 19. 146 00:09:58,795 --> 00:10:02,210 Now, EOF might be a little confusing, 147 00:10:02,210 --> 00:10:05,190 it's an acronym, E stands for end, 148 00:10:05,190 --> 00:10:07,950 O is of, f is file, end of file. 149 00:10:07,950 --> 00:10:10,550 Basically it means it got to the end of the program, 150 00:10:10,550 --> 00:10:15,110 it was sort of in the middle of trying to parse something, and it's saying line 19. 151 00:10:15,110 --> 00:10:17,785 So, I always like to go back and look at the first thing, 152 00:10:17,785 --> 00:10:21,040 before that here's line 17 and sure enough, 153 00:10:21,040 --> 00:10:22,990 I am missing a closing parenthesis, 154 00:10:22,990 --> 00:10:25,180 so it was waiting around expecting there to be 155 00:10:25,180 --> 00:10:30,410 another closing parenthesis and it didn't find it and so it got an error. 156 00:10:31,020 --> 00:10:38,940 Let's run now, and sure enough that works exactly the same as the original. 157 00:10:38,940 --> 00:10:42,990 Now, I actually prefer the original over the second one, 158 00:10:42,990 --> 00:10:46,005 even though line 17 now looks very clean, 159 00:10:46,005 --> 00:10:50,180 we just say key equals this function name, 160 00:10:50,180 --> 00:10:54,400 but I find that the previous version and we can use 161 00:10:54,400 --> 00:10:59,600 our scrubber to go back to it, let's see. 162 00:11:03,180 --> 00:11:09,255 Yeah, this one, where we had key equals Lambda of state, 163 00:11:09,255 --> 00:11:11,730 S cities count of states, square bracket state. 164 00:11:11,730 --> 00:11:15,430 The Lambda expression is more complicated here, 165 00:11:15,430 --> 00:11:22,060 but the lookup of one key in the dictionary is just a very common idiom, 166 00:11:22,060 --> 00:11:25,585 when we are sorting the keys from the dictionaries. 167 00:11:25,585 --> 00:11:32,425 So, that's a little advice on when to use Lambda expressions versus named functions. 168 00:11:32,425 --> 00:11:34,305 My basic advice is, 169 00:11:34,305 --> 00:11:36,985 if a Lambda expression is simple enough, 170 00:11:36,985 --> 00:11:41,440 do it that way and when it gets too complicated to read or write, 171 00:11:41,440 --> 00:11:43,645 then it's time to use a named function, 172 00:11:43,645 --> 00:11:45,965 to move some things out into 173 00:11:45,965 --> 00:11:51,040 another function that you can give a good name for. We'll see you next time.