Python 3, an Illustrated Tour Transcripts
Chapter: Language syntax
Lecture: Unpacking Generalizations

Login or purchase this course to watch this video and the rest of the course contents.
0:00 In this video, we're going to talk about additional unpacking generalizations. This came out in PEP 448 which is in Python 3.5.
0:09 The PEP reads extend usages of the * iterable unpacking operator and ** dictionary unpacking operators to allow unpacking
0:17 in more positions an arbitrary number of times. Let's look at some examples here. If I had a dictionary and I wanted to merge it with another one
0:27 in Python 2 and prior to Python 3.5 I would have to do something like this. I would create a dictionary here called thing_colors
0:36 which is mapping some object to the color. So apple is red, pumpkin is orange. And if I wanted to merge this into a new dictionary with more colors
0:45 one way I could do it is create the new dictionary here called more_colors and then I could say update more colors with thing_colors
0:52 that would insert thing_colors into more colors. And then I could update more colors with other values there,
0:58 note that in this case apple I'm overriding it with green. This PEP allows us to do something like this
1:04 where I say thing_colors is equal to apples is red and pumpkin is orange and more_colors is equal to,
1:11 and then I make a literal dictionary but inside of that I put ** thing_colors in there.
1:16 What that does is it unpacks the keys and values from that dictionary and copies them into more_colors.
1:22 After that, I'm going to insert bike is blue and apple is green, note that apple here is a repeated key
1:29 and so because this apple comes after, where after means further to the right in my literal dictionary here, then this apple mapping to green
1:39 will overwrite the apple that is red. But note that in more colors here, I have pumpkin as orange in there.
1:48 Also note that Python 3.6 the order of dictionary insertion is remembered apple was the first key that I put in followed by pumpkin
1:58 and note that in more colors apple is first, pumpkin is second and then bike is third,
2:02 because this key was already in there, it stayed in the first position, even though the value is updated.
2:08 So an unpack can be in any location in the dictionary in the previous example, it was at the very start
2:13 but it can be at the end or you can have actually multiple unpacks in a dictionary Here I say bike is blue, apple is green
2:22 and then we're going to unpack thing_colors in there, in this case the apple that's red from there overrides the apple that is green.
2:30 But note that bike and apple are in first and second position because they were in the original dictionary. Another nice feature of this change is
2:40 it allows us to have multiple ** operations in function calls here. Note that here I'm calling this function print args,
2:47 which takes variable number of keyword arguments and I'm saying I want to pass in thing_colors unpacked and also more_colors unpacked.
2:56 This one didn't work prior to Python 3.5, but in Python 3.5 and above you can do syntax like this
3:02 and note that I'm putting in another named parameter here with a value in between those.
3:08 One thing to be aware of though, is that you can't repeat names in a call. So this might be a gotcha here.
3:14 Here I've got thing colors and I've got apple is red here, I've also got more colors apple is green
3:20 and if I call this with thing_colors and more_colors with these repeated keys, I get a type error. In the prior example on the previous slide,
3:28 I didn't repeat that apple key and so I didn't get this error. So this is something you might need to be aware of if you're repeating those.
3:35 Simple way to get around that is just to merge those dictionaries before calling them in there, that's something that might happen.
3:42 So that's the ** operation that allows us to unpack into dictionaries and also use unpacking and function calls in more than one place if we want to.
3:52 Let's look at the single star, single star allows us to create tuples. So here I've got name is equal to Matt.
3:59 Remember that the string Matt is a sequence of characters here. And if I say *name, with a comma at the end here, it's going to give me back a tuple.
4:11 Note that I'm not doing this extended unpack operation, there's no assignment here, so this is slightly different than the prior examples
4:19 where I would get back a list, but this is saying I want you to take what's in the sequence and stick it into a tuple.
4:25 This is also a case where you might need a comma if I have name is equal to Matt and I just say *name on itself,
4:32 I get this error here, syntax error, can't use a star expression here. Here, I've got some examples of various ways we can use star expressions
4:40 and know that by default, these return a tuple and I can actually string these together by putting a comma
4:47 and use multiple of them and here I have a tuple, note that there's parentheses here with all of the characters from name and last in there,
4:56 if I wanted to put those into a list, I just put square brackets around those and that puts it into a list.
5:04 Similarly, I can put it into a set, note that a set is not ordered, so the order comes out a little different than what the order is in name and last.
5:13 Here I've got a little function called summer that just takes variable arguments and variable keyword arguments
5:18 and it's going to sum all the arguments that are passed in in positional locations and it's also going to sum all the values
5:25 so it's not doing very much, it just accepts arbitrary number of arguments and sums them if they are positional or values in keyword arguments,
5:34 let's look at some examples of calling this, I can call it with 1, 2, 3, any number of positional arguments and it gives me 6.
5:41 I can also call it with star list here and then a three following that, and that's fine, Python 3.5 and above doesn't complain about that.
5:51 Note that I can also have multiple stars here and this can be a list here, it can be any sequence here, and I can have
5:59 however many stars I want to in that, if I want to, and here I'm calling it with a star, a positional parameter
6:04 unpacking a dictionary here, a keyword parameter here and another unpacked dictionary over here and that works as well.
6:14 Little bit of the difference between this syntax and the extended unpacking that we showed in another video,
6:20 here I've got name is equal to the string Matt. I can do the extended unpacking by doing an assignment here on the left-hand side
6:27 by saying *letters, I need the comma at the end there is equal to name that makes a new variable called letters
6:34 and it is a list with the individual characters in it. Note that in this unpacking generalization,
6:40 which is different than the extended unpacking defined in this PEP here, I am not putting this on the left-hand side,
6:46 I need to put it on the right hand-side, I put a star in front of it, a comma at the end
6:51 and I assign it to a variable and it gives me back a tuple here. So a little bit of a difference between those two,
6:57 if you need to create a list you can use this extended unpacking. Note that if I simply put square brackets around that
7:05 I will also get a list on the second example. This video talked about additional unpacking generalizations, which is pretty cool.
7:14 If you want to create dictionaries from other dictionaries or merge dictionaries or create tuples or lists or sets from sequences,
7:22 you can easily do this with this new syntax. You can also pass in multiple unpacking operations into function calls, which is cool as well.


Talk Python's Mastodon Michael Kennedy's Mastodon