Write Pythonic Code Like a Seasoned Developer Transcripts
Lecture: Merging dictionaries
0:01 Next, let's talk about taking multiple dictionaries
0:03 and combining them into one that we can use
0:04 to look up items that came from various places.
0:08 Here in PyCharm, I have a sort of web example for you,
0:11 imagine that you are writing a web app,
0:14 there is data coming from different locations into your action method,
0:18 so on one hand we have routing setup that is passing data through the URL,
0:22 we might be in that location, passing the id and the current value might be this,
0:27 the title might be that, we also might have the query string
0:30 and the query string might have some other value for id, like 1,
0:33 it might have a separate value it's adding to the mix here called render_fast is True,
0:38 then maybe we are also, as part of posting long URL
0:42 which matches the route with the query string we are posting back a form
0:45 and that form has email, a name and it is well.
0:49 So here I am just going to print out these three dictionaries
0:51 just so you can see what they look like, and no surprise, here they are,
0:55 they just look like basically they are written here,
0:57 so what if I want one dictionary that I can just ask - "what is the id,
1:01 what is the user name or what is the email address?" -
1:06 and not have to worry about which one is located
1:09 and we have our super non-Pythonic way here
1:12 and I am going to use this dictionary called "m1",
1:15 we'll go like this, and I'll say "for k in" and what we are going to do
1:19 is we are just going to loop over each dictionary and stick the value in there.
1:23 The order in which we do this matters.
1:25 So let's suppose we want the query string that has the least value,
1:28 so we are going to put those values into this combined dictionary first,
1:32 so we'll say like so, and then we could just go to "m1"
1:34 and we can just set the value for whatever the key is,
1:38 to whatever the value and the query dictionary, here's like that.
1:44 And, we'll do the same thing for let's say
1:46 the next thing we are going to do is the post,
1:50 like that, and finally, we'll do it for the route.
1:55 OK, so if we run it, we should get a dictionary because the route has higher priority,
1:59 with id 27, title Fast apps, render_fast is True and then that data in it.
2:04 Let's run it, all right, id 271, like we expected, Jef, Fast apps, perfect,
2:11 so it looks like you combined it well,
2:13 but this is a very procedural way, and there is better ways,
2:16 so in Python down here we can actually sort of improve upon this
2:21 by leveraging a couple of methods on the dictionary,
2:24 so we can go like this, and remember
2:26 we wanted the query first so we can say "query.copy"
2:29 and actually create a copy of the dictionary
2:31 and then we can go here and we can say update,
2:34 I would like you to update your values possibly overwriting them with "post",
2:37 and then I would also like to overwrite this with the route.
2:41 So now if I run it, we should have the exactly the same output
2:44 but a little safer, less fiddly.
2:48 OK, you can see these are the same dictionary,
2:50 now notice there is nothing about dictionaries that are ordered,
2:53 so they are going to be out of order but they are the same value,
2:56 down here this "no", I wrote some code that checks
2:59 whether these four dictionaries "m1", "m2", "m3" and "m4" are the same.
3:05 We are not finished yet, so they are not going to be the same.
3:08 But in the end, we write these better versions here, we should be good.
3:11 We can actually do this in one line with the dictionary comprehension,
3:14 it's not pretty but it does work.
3:17 So, let's imagine where they end, we can say "for d in"
3:22 and we can put all of our dictionaries in the order we care about,
3:25 "query, post" and "route" and so for each one of those we can come back here
3:30 and say "we would like the key:value" and we'll go for each one of these,
3:35 we'll say "for k,v in d.items"
3:42 So here you can see exactly the same dictionary, matching ordering,
3:45 let's do a little formatting on that.
3:48 OK, so we are looping over all the dictionaries
3:50 and for each dictionary we are looping over,
3:52 we are looping over and point out the key
3:56 and the value from the items and then we are creating the dictionary from that.
3:59 So, this works, I really don't like it very much, even though it happens in one line
4:04 and it feels like oh that must be Pythonic because look at it,
4:07 it's cool and special and declarative.
4:10 To me it's hard to look at it and not go "oh,
4:13 I see you are combining those dictionaries",
4:15 so given the choice between the classic Pythonic way
4:18 and this dictionary comprehension way,
4:19 I would actually prefer the one above,
4:21 because this is really clear to me what's happening.
4:23 Maybe that's just me.
4:25 But in Python 3.5 they introduced a really cool way to merge dictionaries,
4:30 so if we were going call a function, so let's say some function,
4:35 and we want to take a dictionary and pass it as keyword arguments here
4:39 I could say **query say,
4:41 if I wanted to pass the values from the query,
4:43 but they kind of apply that same syntax here to say
4:46 I would like to merge all the values from - let's start with query,
4:51 all the values from post and all the values form route.
4:55 so this does not work on Python 3.4 and below so be careful.
5:00 It's only Python 3.5 and above,
5:03 let's run it and make sure it does what we expect.
5:06 Boom, look at that, there is a last one we just wrote and if we actually do
5:10 a comparison of the values ignoring order, these are exactly all the same,
5:15 so here we have the super non-Pythonic way,
5:19 we have the sort of classical way of doing this,
5:23 leveraging the dictionary features,
5:25 we have the "clever but too clever" in my opinion way of
5:29 looping over the dictionaries and looping over their key value items
5:33 and recombining them,
5:35 and then we have the quite sleek Ptyhon 3 way of the **dictionary
5:39 to unpack them, back into a dictionary.
5:41 And notice, it has the same overwriting process where the id from the query
5:46 was overwritten by the id from the route because the route came last.
5:50 Let's see that in a graphic.
5:52 So, here is our three dictionaries and our non-Pythonic way
5:56 we create a blank dictionary and we just loop over all the items
5:59 and we just start filling it up, very procedural, not amazing.
6:01 But instead, we can use the Python 3 that is 3.5 actually quite high,
6:06 way of unpacking the dictionary back into a dictionary
6:09 so this **query **post **route becomes a new dictionary.
6:13 Very nice.