Write Pythonic Code Like a Seasoned Developer Transcripts
Lecture: Dictionaries as switch statements
0:01 The Python language has no switch statement.
0:04 We have "ifs" and we have "for...in" loops and we have "while" loops
0:06 and that's about it. No switch.
0:09 But, we'll see that with a dictionary, we can actually simulate a switch statement,
0:13 so let's look at that in PyCharm.
0:16 Let's see what program we have here.
0:17 So it starts out by asking which direction presumably do you want to move,
0:21 we have this little character, his name is Chippy,
0:24 so Chippy is going to move in a direction,
0:26 and what we need to do is we are going to ask,
0:29 provide some options: North, South, East, West, South-West, that kind of thing,
0:32 and then we are going to parse this into a moves enumeration,
0:37 you can see we have these various options here,
0:39 so we are going to focus on this parse method
0:42 and then later we'll have a quick glance of this move method as well.
0:45 So down here, we have the standard parse
0:49 and what we are going to do is we are going to go through all the possible cases,
0:52 if you have a "w", we would like you to move West,
0:55 if you have an "s", we'd like you move South
0:58 or we'll parse this to a "moves.south" and so on.
1:01 So we'll see that this whole segment here can be replaced.
1:05 How does that work?
1:06 You can replace all these tests for if with basically a key access
1:10 so let's go over here and we'll call this like parse_dict or something like that,
1:15 and we can just start printing the values
1:16 so for "w" we are going to have this one,
1:21 for "s" we are going to have this one, and so on,
1:25 let me zoom ahead to build this whole dictionary.
1:29 So here we have our dictionary built,
1:31 so how do we use this to actually replace that "if" statement,
1:34 we'll just say "return parse_dict.get(text)",
1:40 so we are actually doing two things here,
1:41 one we - are looking up the values for each "if" statement
1:44 by going into the keys here and because we are using "get"
1:48 rather than indexing directly into it,
1:50 we are actually providing the default return value
1:53 that was at the very end of that "if" statement, cool, right?
1:57 So let's run it and make sure that this still works,
2:00 so we want to move South East, it says "You chose:
2:05 Moves.SouthEast", we print it out to just see what we parse to make sure
2:08 that that's working, and then Chippy moves South East, yupi,
2:11 what if he goes North? Oh, Chippy is moving North,
2:13 so really cool and clever way to build that switch statement
2:16 for certain circumstances,
2:18 when you have this really large set of possibilities.
2:21 Theoretically, it can even be faster; so what we have done here
2:24 is we basically have returned the value given a particular case,
2:29 but in switch statements, you can also call functions, right?
2:32 It's not just a matter of saying "we are going to pick a value"
2:35 but you can actually say "we are going to run this block of code
2:38 if this case matches or that block of code if that case matches."
2:42 So let's move down to our character here and make a change there,
2:45 so, right now it just prints out the same thing, no matter what direction you move,
2:49 but what if I wanted to do something like this,
2:52 "Direction == Moves.North", let's print,
3:02 "character name moves North with a special hesitation",
3:05 "else", otherwise we'll just print they move in some direction.
3:11 So let's test this.
3:12 All right, so if we move South East, "Chippy moves South East",
3:16 if you move North though, "Chippy moves North with a special hesitation",
3:20 so could we take this behavior and actually
3:23 make this into a dictionary switch style statement?
3:26 Answer is of course we can, so what does the dictionary look like?
3:30 So we are going to need again to define the keys
3:34 but this time the key is going to actually be the value for direction,
3:38 and I added a little type annotation here to say this is moves,
3:41 so this would be like a Moves.North
3:44 and then we are going to put something here,
3:46 let me just put None for a minute,
3:48 so we have one for North and one for South.
3:51 So what we need to put here is executable code,
3:53 we could put a function name that we write somewhere else,
3:57 or we could just write a lambda,
4:05 something like this,
4:06 "Character moves North with the special hesitation", and so on.
4:11 Now let's just put these two for a minute,
4:13 just to see how this idea is going to work,
4:15 so here we have our action_dict and let's have a default_action
4:19 that we will use if for some reason we get a move we don't expect.
4:24 So here we've got default action "so and so moves quickly to such and such direction."
4:28 So then, what we can do is I can say the action is equal,
4:32 I am using a lot of variables here,
4:34 we could sort of inline this more possibly but trying to be really clear for you,
4:37 so "action_dict.get" and we are going to give it the direction,
4:42 but we can also give it the default, action so that
4:45 if there is no direction method we get this default one
4:48 and then we can just call "action()"
4:50 Like so, OK, let's run this.
4:53 What directions do we have to move? We could say North,
4:55 we should see "Chippy moves North with a special hesitation",
4:59 awesome, let's go South, "Chippy is going South for the winter!"
5:04 Now, if we run this and we go South East which is not on our list,
5:08 "Chippy moves quickly to Moves.Southeast"
5:12 Cool, right, so basically here is our switch statement,
5:15 we probably could inline this a little bit better,
5:17 like for example this probably makes more sense inlining,
5:20 it's, PEP 8 says we should define this as a "def" if we are going to write it that way,
5:25 so we can do this, that's a little on a long side,
5:28 maybe we format it like so, of course,
5:30 we want to fill this out for all the reasonable actions that we'd like to handle,
5:35 so this is nice for really short, small bits of executable code,
5:38 I wouldn't write too much code in these little these lambda expressions here
5:43 but using this to select values
5:46 as if you had a bunch of "if" statements, this is really nice,
5:50 so let's see this concept of dictionaries as switch statements in a graphic.
5:53 So here we have basically the code that you just looked at,
5:57 the moves lookup, we are going to let these specified "w" for West,
6:00 "e" for East, "s" for South and so on,
6:03 then we just say "dictionary.get", give it the text we want to switch on, conceptually,
6:07 and we'll either get one of the values we specified or we get None
6:10 which is a pretty reasonable response for "Hey, I couldn't parse that value."
6:15 We saw that these values that go into the dictionary, like in this case
6:19 Moves.West, it doesn't have to just be a value,
6:21 it can actually be an executable function as we saw on our character class.