Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Methods and Functions
Lecture: Leverage inline methods with lambda expressions
0:01 The first highly Pythonic concept that we are going to talk about are these things called lambda expressions.
0:07 These are like small, inline methods that you can pass around, chain together and build larger expressions from.
0:13 Let's look at the idea of using functions as a parameter in the first place. So, here we have find_special_numbers,
0:20 now this function is just going to go through some set of numbers and it's kind of hokey I know, but it's going to loop through a bunch of items,
0:27 in this case the numbers between 0 and 10 and it's going to apply our selector,
0:32 so a special selector is a function that takes a number and returns a boolean. So we can call the function, pass it a number
0:39 and it will say this number should appear in our list or maybe it won't. Now this method might look for even numbers,
0:45 it might look for Fibonacci numbers, it might look for prime numbers, I don't know.
0:50 That's the point, we can pass whatever type of function we want in here and the selection part will be done by that function
0:57 whereas the gathering and looping part will be done here. So let's look at this idea in Python.
1:03 So, down below we have our find_special_numbers, just like you saw in the slides, and I've written this other function called check_for_odd, right,
1:11 you can see it's doing the standard modular check_for_odd numbers; so we can come up here, we can combine these two things together, like so,
1:20 we can say "for n in find_special_numbers" and this takes some kind of a selector, so I can say check_for_odd.
1:30 Now, PyCharm automatically tries to call this function, but I don't want to call it, I want to just pass it, all right,
1:35 we'll see that is I take this and I actually print out this here, maybe I'll even do the type for you, do the type and then the actual value of it,
1:46 we'll see that this comes out as a type of function and a particular function pointer to a particular type of function.
1:52 So just like any reference, we can pass it here maybe we want the first 50 numbers, we'll just print those out.
2:00 And let's print them all in one line so that you can see them, so we use a separator of comma to just comma-separate these values, so let's run this.
2:08 Perfect, so you can see we've got our prime numbers here, including the first 50 prime numbers that we were looking for.
2:14 And also see what we printed out our type of check_for_odd, we've got the type as a function
2:19 and it's a particular function "check_for_odd at that address". So that's cool too.
2:24 Now, this works fine, but writing this check_for_odd function down here every time I want to be able to pass a function around,
2:31 this is kind of- well odd, so it works fine, but it separates the implementation from where we are using it,
2:39 and if the implementation is really simple, it can clutter up your namespace with all sorts of little functions
2:45 and it can move where you are using them from where you are defining them so it's a little harder to understand what's going on.
2:51 Let's take this basically the same idea here, and maybe so it doesn't shoot all the way off the screen we'll lower that number,
2:58 and we can come down here and we can say "I want to do the same thing but this time I want to check for numbers divisible by 6
3:03 and I want to use a lambda", so let me just write it on a separate line first.
3:08 Call it "check = " and then we could pass the check just so it's more clear, so with the lambda expression I would like to just say
3:14 given some number "i", I would like to somehow say "return i % 6 == 0", right, now this obviously is not the right syntax,
3:26 given this, I don't know, this value goes here and just sort of passes this little bit of code, so in Python the way we say - we are defining lambdas
3:36 you say lambda and then the arguments, the parameters, and you say colon is your separator as you normally would,
3:42 every lambda has a little expression of value it creates and it returns so you don't say the return value, so there,
3:49 this is our lambda expression, now if we run it, it should work. Perfect, here are divisible by 6 numbers,
3:56 so it works, but PyCharm here is saying: "you know, not so much, PEP 8 says don't define lambdas outside of their actual use as pointers",
4:05 rather we should do a little miniature "def" here, so let's inline this as it's kind of meant to be used. There,
4:12 so we can just take our lambda expression and pass it as a parameter, and that's what lambdas are for, you can create these little expressions
4:18 that you can chain together pass these parameters and so on. So we should get exactly the same behavior if we run it.
4:24 And we do. Cool, so if we have to just come up with these little bits of code, here
4:31 and pass them around, lambdas are beautiful for this, let's look at another example.
4:36 So here I have a bunch of words, and I would like to have them sorted, I'd like to have them sorted in a way that regular people would say
4:45 "yes, those words are sorted alphabetically." So one way you might say "let's give it a shot" is we could just come over here and say "words.sort()".
4:53 Now, whether I use sort or I could say sort it, these will generate sorted list that I can then go and work with,
5:00 the difference is this changes the underline list of words whereas this returns a new copy of it that is sorted,
5:07 so it doesn't really matter, we'll go with this one for now. So let's try to sort like so and see what we get.
5:12 OK, 'CPython', 'Please', 'a' and 'changes,' - these look sorted, and those look sorted, but as a group they don't look sorted to me.
5:24 That's because right now the sort is case sensitive, OK. Well, what do we do, are we just out of luck, do we have to write our own sort algorithm?
5:32 No, of course not, so what's cool, let's comment this out, because it almost works but not quite.
5:37 In both versions of sort, they let you specify a key selector, and what this key selector is, is it's a function that given one of the items,
5:45 in this case a word, we can return something that we'll actually use as the sorting value, the comparison value, so we could put a function here,
5:54 but I am going to define a lambda expression, so I'll say "lambda w for word goes to" -
6:00 well, if we just put it like this - "w" it will do the same sort but I actually want to sort without regard to the case,
6:07 so let's do this, let's say lower any time you want to compare word, do not compare the actual word, compare the lower case version,
6:15 we could use upper and so on. Let's try it. Now look at that, that looks sorted, doesn't it?
6:21 And look how incredibly easy this is, "key=lambda w: w.lower()" That shows you some of the power of lambda expressions in Python.
6:31 Let's look at that in a graphic. So here again we have our find_special_numbers,
6:35 we also saw the same situation applies to built-ins like lists and so on, so we want to pass some kind of selector and we could write a special method
6:42 somewhere using "def method name da da da" and pass it but if it's a small little test, it makes much more sense to do this
6:49 as an inline lambda expression, like so. So we just write "lambda, arguments, goes to, return value" basically.
6:57 If there is no arguments, you just say "lambda:", you get multiple parameters like any other method as well.
7:02 Using lambda expressions is a very Pythonic thing to do.