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