Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Foundational Concepts
Lecture: Multiple tests against a single variable

Login or purchase this course to watch this video and the rest of the course contents.
0:01 Now let's talk about multiple tests against a single variable.
0:04 What do I mean by that?
0:06 Here is an example, suppose we have an enumeration of moves,
0:10 North, South, East, West, North-East, South-West, things like that,
0:14 and we would like to test is this a horizontal or vertical move
0:18 or is it a diagonal move?
0:20 So somehow we have received a move called "m",
0:23 from somewhere maybe this is in a game or something,
0:26 and we want to check is it one of the direct, vertical or horizontal ones
0:30 so we would say "if m is North, or if it's South, or if it's West, or if it's East,
0:35 then we are going to match this case."
0:37 So this is very common in many languages but in Python,
0:40 we'll see there is a more Pythonic way of doing things.
0:43 So here we are in PyCharm and we have basically the situation I just described.
0:48 You can see we are in our moves enumeration
0:50 and it has these various moves,
0:52 the four horizontal-vertical ones and the four diagonal ones,
0:56 and it even has a parse method here,
0:58 parse static method and we are going through
1:01 and we are actually checking hey if we are given a text
1:04 and the text lower case version is "w"
1:09 then we are going to parse that to West, if it's "e" then it's East,
1:13 "nw" is North-West and so on.
1:15 Now we'll see if we can actually improve on this as well
1:18 but that's not the point of this conversation,
1:21 OK, so we are going to run our code
1:22 and it's going to ask for which direction we want to move,
1:25 North, South, East, West and so on
1:26 and we'll use that parse method you just saw.
1:28 If it's something it doesn't understand
1:30 it returns None and as we already discussed
1:32 we check if it is None, then we bail or print it out
1:36 so just you can see what the parse did as and
1:37 and then here is this code that we have before.
1:42 So, let's first run this to make sure it works,
1:44 OK, "which direction you want to move?"
1:45 Let's go South-West, move South-West was parsed,
1:49 hey that's a diagonal move;
1:50 we'll try another one, let's try North. North, that's a direct move,
1:54 maybe the name is a little off but you get the idea.
1:57 So let's write in more Pythonic version here.
2:04 recall in Python that if we have a collection,
2:08 like a set or something like that,
2:10 if we say "s = {1,2,9,11}", we can check for containment
2:17 and in this set using the "n" keyword,
2:20 so if we have "v = 11", we could ask we could say "print v in s"
2:27 and because 11 is in the set it should come back and say yes,
2:31 so let's just say something here, True, yes it's in there.
2:34 We change this to 12 and run it again, we'll see it False, it's not in there.
2:39 So we are going to use this principle to make our test more Pythonic.
2:42 So we can make this shorter, less error-prone,
2:45 easier to read and more Pythonic using that idea,
2:48 so what we'll say is "if m is in the set of moves to the North,
2:54 moves to the South, moves to the West or moves to the East", like so,
2:59 we could use a list, we could use a dictionary,
3:02 but set seems like the right things for what we are trying to express here.
3:05 Let's just run it and make sure that this still works.
3:07 So if we move North, it's a direct move,
3:10 if we move South-East that's a diagonal move.
3:12 Let's just try, let's take West, boom, direct move.
3:17 OK, so that's pretty sleek, right?
3:19 So when we have a single variable
3:21 and we want to test it against multiple conditions, use this "in" keyword,
3:25 now this is extremely readable, but in fact,
3:27 it would be a little bit slower, so most of the time,
3:31 a little bit slower in something like this is you know,
3:35 a millisecond here, a millisecond there, nobody cares, it doesn't matter.
3:38 But if this happened to be within a really tight loop,
3:42 we could improve upon this by taking this set we want to test for
3:46 and moving it outside the loop.
3:47 So we could do some kind of refactor and create a variable here
3:50 and call this say a direct_moves, like that;
3:54 where this gets put somewhere outside of our loop
3:59 and then inside of the loop we can test it like this,
4:02 again this should still work, just like before;
4:04 North, yes that's a direct move,
4:07 but sometimes you may want to avoid this for performance reasons.
4:10 Let's just do a quick little test to actually understand
4:13 what the performance implications are.
4:19 So here we are going to do a "for...in loop" one million times
4:22 and let's start out with the version that is not so Pythonic with the multiple tests,
4:28 we'll just compute the boolean over and over and over
4:30 and see how long that took.
4:32 So let's run this.
4:33 So it took 0.2 seconds, so 200 milliseconds for a million moves,
4:38 chances are this doesn't really matter for you,
4:41 but if we want to figure out how long that took for one,
4:43 we could do something like this,
4:45 so 10 to the -7, extremely fast but like I said,
4:50 if you do it in a million times, hey maybe it matters,
4:53 let's test a version that is more Pythonic but slightly slower.
4:57 Here 0.3 instead of 0.2, no big deal,
5:00 however we wanted allocating the set each time to the loop,
5:03 you'll see this is fairly slower.
5:08 So 2 seconds, instead of 0.2 seconds,
5:10 so that's like 10 times slower,
5:12 so you really have to decide how much does this performance matter
5:16 you can see it's almost entirely negligible
5:18 when you extract it outside of the loop, and you write it like this,
5:24 it's still quite fast but it does put indent in when you do it this way.
5:31 So here I commented out a little test if you want to play with it,
5:33 feel free to uncomment it,
5:35 you should really thrive to do this, this sort of test here,
5:37 and maybe I'll make it the most readable version
5:39 until we have a performance problem, so we can inline this here,
5:45 excellent,
5:46 so here is a nice Pythonic way to test a single variable
5:50 against multiple values in Python.
5:53 So this is probably the most natural way to write this code
5:56 coming from somewhere like C++, Java, C# and so on,
5:59 however, in Python we can use this set and the "n" operator
6:04 to make this much readable,
6:06 now if we want to see all the cases,
6:08 it's very easy just look at what's in the set if you want to add or remove one
6:11 easy to do and you won't miss an "or" with an "end"
6:15 or drop a parenthesis or something weird like that.