 In this video, we're going to learn about a nice application of tuples. It's called unpacking. So we saw unpacking before, shortly, when we talked about list operations. So I showed you the asterisk operator, which is not an operator, but a syntax that unpacked the contents of a list inside another list. So we already saw one application of that. And implicitly, we also saw tuple unpacking in a couple of other places, but we didn't call it like that. So let's create a new file and rename it into tuple unpacking. And let's talk a bit more deeply about that. So let's start with an example. Let's simply create a list of numbers. And I'm going to use the numbers from 1 through 12 that we always use in this course so far. So this is the list numbers. So it's a list object, right? So what do I mean by unpacking? So one application of unpacking goes as follows. Because we have now 12 items or 12 elements in this list, what we could do is the following. I could say, let's say v1 for variable 1. And let's also write v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, and finally v12. So I'm basically defining 12 variables simultaneously. By doing the following, I'm simply assigning them the numbers. Actually I'm taking numbers and assigning it to these 12 variables on the left-hand side. So before, we usually only saw one variable on the left-hand side of an assignment statement. Now this is the first time where I show you more than one variable on the left-hand side of an assignment statement. And this is an application of unpacking and packing, so to say. So where's the unpacking? Well, numbers we know is a list of 12 numbers. And these numbers are being unpacked individually into one variable each. So let's execute it so, first see it works, the Python doesn't complain. And if I now look at the variable v1, I see its value is simply 1, coming from the list. So now you may wonder, what happens if you get the wrong number of variables? So maybe let's get rid of the v12 here. And now we get an error message and it says, too many values to unpack, okay? So expect at 11. So what does that error message mean? So on the left-hand side we have 11 variables. So Python is expecting 11 elements to be unpacked. However, the numbers list, when unpacked, has 12 elements in it. So it's one too many. And Python simply doesn't know what to do with it. Similarly, if we go ahead and add, let's say, v12 back, and let's also add v13, we also get a value error and now it says not enough values to unpack. So in other words, Python is now expecting 13 variables. However, the list only provides 12 elements. So for the last variable, we don't have a value to assign to. So in other words, when we use this unpacking syntax here, then we need to get the number of variables right on the left-hand side. However, there is a nice syntax that avoids us in what it helps us in such situations. So let's assume you're only interested in maybe the first element in the numbers list. And maybe also, let's say, in the third one. So how could you write that? Well, we're going to write first comma underscore. So underscore is a valid variable name, but it's a convention, and the convention is when we use the name underscore for a variable, then we're basically communicating that we need a variable for syntactical reasons, but we don't want to keep the value. We're not interested really in it, but we need to put some variable here, and that is just a convention in the Python world to put an underscore in such scenarios. We've seen the underscore before in a for loop where we did not need the variable over which we looped, right? Now let's write third, and let's assume all the other elements after the third one we don't really need. So what we could do is the following. We could use the star syntax that we saw in the video on list operations the first time, and we could pack the remaining elements into a variable called rest. So let's do that, and let's assign on the right-hand side number. So numbers is now split into the first element, the third element, and the remaining ones. So let's do that, and we see we get no error message. So in other words, this star here avoids this error message that we got on the previous two cells for not having enough or too many variables on the left-hand side. If I check first, it is one. If I check third, it will be three. And now if I check what is rest, it is a list of the remaining elements. Unfortunately, it's a list. So this is always going to be a list on the left-hand side. It's still called, so unpacking is usually in the context of tuples. But we know that we have learned before that tuples and lists are basically the same thing. The only difference is lists can be mutated after they are created, and tuples cannot. So tuples are like immutable lists, that's what we said in the previous video. So that is on the left-hand side. So what we are doing here, on the right-hand side, sorry, what we are doing here, this is unpacking. So we are unpacking the elements of the list. And on the left-hand side, we are packing, which is the opposite. So the remaining elements that are not going into the first, the underscore, and the third variable here, so the remaining ones, they are packed inside the rest variable. So unpacking on the right, packing on the left. So in other words, unpacking means we just unload everything, and packing just means we get whatever we get and put it in one thing, in one bag. So in terms of packing and unpacking, they are really intuitive here. So this is how we can unpack stuff. So now, where else does this unpacking and packing happen implicitly? So let's assume you have a for loop. So let's say we have numbers. And let's assume, in addition to numbers, we have a list called, let's call it names. And names is a list. Let's make up a couple of names. Let's make up the first name, Achim. The second name is going to be Berthold. And the third name is going to be Caesar, okay? So now what we are going to do in the next step is we are going to use the zip build-in to zip together the two list objects. So this is something that was explained, I think, in chapter four. So we are going to use a for loop, and we're going to say for, let's say, number, singular, comma name, singular, in zip. And then within the zip build-in, we put the numbers list first because number comes first. We'll put numbers first as well, and names. And if we now go ahead and let's say, for example, say print number, comma name, what we see is this for loop is going to run three times, okay? Why three times are not 12 times? Well, obviously the shorter list wins here. So once the first of the two intervals here runs out of elements, then the entire zip build-in does not produce any more elements, so to say. So the shorter one wins. And zipping is just like a pullover. You can zip stuff together, so that is where the term comes from. And now what does that have to do with unpacking and packing? So I can show you something. So maybe let's copy-paste this same cell here, and instead of having two variables number and name as a singular, we are going to simply call that x now, 1x. And we are going to print the x here. And what we see here when we do that, we see now x becomes a tuple where the first element is a number and the second element is a name. So in other words, the zip build-in provides us with tuples, okay? And now what the upper of the two versions does, this one here, this syntax, number, comma name, this also unpacks the tuple, okay? So in other words, we get from the zip, we get tuples, and the tuples are here unpacked. So we could also go ahead and also print out the type of x just to be sure that it's a tuple. So what here we see, we can confirm the zip build-in gives us back tuples. And here in this line, we are unpacking them, okay? So let's maybe put a nice header on here and say unpacking in for loops, okay? So this is something we have seen before in I think chapter four, this is when we saw that the first time. There are also other build-ins that do something similar like the enumerate build-in, for example. So maybe to review that, what we also could do is we could say for i as an index, comma name in enumerate names, print i comma name. And now we get zero, one, two. And the reason why is enumerate gives us back an index number plus the next element in the interval that it takes. And by default, it starts with zero as we see, but we could also provide it an optional start value, let's say start equals one. And now we get back one, Achim, two, Bertolt, three, Caesar. So enumerate and zip, in this case, they do the same thing. They provide us back with a tuple of two elements, so a number and a name. And we are going to unpack them either by writing number comma name or in this new version here down here by saying i comma name. So we are unpacking stuff, okay? So that's a very similar idea, it's actually the same idea, then unpacking above here. It's only happening in a for loop, okay? So that is unpacking. So now let's look at one more thing in this video. Let's look at packing and unpacking in the context of functions. So let me write a function first, because the example will probably speak louder than any words that could describe it. So let's define a function. And the function is simply going to take some argument. And let's think of an example. So let's think of a function that takes many arguments and it simply multiplies them together. So the arguments have to be numbers. So let's call the function product. And product should take a couple of arguments. And now the question is, so far in this course, we had to provide a parameter for every argument the function should take. But now this function should take as many arguments as we want. So we may give it one number, we may give it 10 numbers. But it doesn't matter how many numbers I give it, the function should multiply them together, right? So there's a syntax and it is what you've already seen before, the star syntax. So the star syntax is in this case, packing. So in other words, when I pass this function more than one argument, they're all packed together in the variable called arcs. But let me finish the function first and then we are going to see. So the function simply multiplies all arguments. So let me define the function. So let's say our product to start with, so maybe let's call it RV for return value. So let's call it result, that's even nicer. So our result to start with is simply one, because one is the neutral element of multiplication. And then we are going to say for arc as an argument in arcs, so I'm looping over the arcs here. And I'm going to say result is equal to new result will be set to the old result times the argument. And we can make that short, so we can abbreviate that by simply saying times equals arc, okay? That is the short version. And then after the for loop, we are simply going to return the result. And we could put in two empty lines to make that logic a little bit more apparent here. Okay, so that function is now built. So let's go ahead and use the function. So let's call the function without any arguments. And we see the function gives us back one. So why is that? Arguments internally is going to be a tuple. That is why this video is under the part in chapter seven where we talk about tuples. So internally arcs is going to become a tuple. And this tuple is going to be empty. It isn't a tuple with no argument with no elements inside. Therefore, this for loop does not even run a single time. It is simply skipped. So in other words, we set result to one, and we simply go down to the return result. That is why the function simply returns one. If I go ahead and I call the product function with one argument and I pass it to number two, I get back two. Why? Because one times two is simply two. Let's go ahead. Let's say product of let's say two and three. And now I get back six. So one times two times three will give me six. So now here you get the idea that you can give this function as many arguments as you want. So we can go ahead and we can say, let's give it three ones, maybe three twos, and three. And I get back 24. So this function can now take as many arguments as we want to pass it. And it can process them. So that is what the star does. Okay. So in other words, the star here is packing. Okay. It packs together all the arguments that we pass it into one tuple. Just to illustrate one further point. I'm going to temporarily print out a debug message by saying print type of arcs. And the reason why I do that is to simply show you that internally arcs within the function is just a tuple, okay? So here that's the confirmation. So this is just built into Python. This is just Python's way of how to deal with that. So this is packing with in the context of function calls. And now we do the opposite. We do unpacking. And I give you a very similar example. So above we define a list called numbers, a list of 12 numbers. And let's say I want to multiply together these 12 numbers. So let's go ahead and call the product function. And I pass it as the argument, the numbers list. Let's see what happens. We get back a list, okay? So why do we get back a list? That shouldn't happen. We should get back an integer, really, right, a number. So let's try to find out what is the semantic error behind that. So let's scroll up. So if I pass, so how many, first of all, how many arguments do I pass the product function in this call here down here? Well, the answer is one only, right? Just one, one list. Even though the list has 12 numbers in it, the function only gets one argument. So internally, arcs will become a tuple that has one list in it, one element. So it is a tuple that has a list that has the numbers. It is not a tuple with numbers. It is a tuple that has a list that has the numbers. Therefore, therefore what's going to happen is we take the result, which is one, and we are going to multiply. This follow is going to run exactly one time, because there is one argument given, and the follow is going to run once for every argument. And it is going to multiply one times a list, because the one argument that we give it is a list. Now, you all know what happens if I multiply a list with a number. So one times numbers. It simply gives me back another list, the same list. If I do that with, let's say, two times numbers, I would get back the list duplicated. But it's still one list. So this is a list concatenation, right? You remember that. So this is what's going on here, and this is why we are getting back a wrong result. So what we really want to do is, I don't want to give the product function a list as the argument, but instead I want to give it the numbers that are within the list as arguments. So how can I do that? Well, I have to unpack numbers. And we saw in the video on list operations already how to unpack a list. We use the star syntax right here. So note the difference. Maybe I'll leave that in so that you can compare later on. Let's say they're going to call the product function and say star numbers. And now I get back some big number. And these are the numbers from one through 12 all multiplied together. Okay. So now what's going on here? Well, the star here, the star numbers, is going to unpack the numbers list, which means the product function is being called with 12 arguments, not one, but 12. And then internally the product function takes the 12 arguments and packs them together into the arcs parameter if you want. And then you have internally a tuple with 12 numbers. So we call the function by unpacking a list of 12 numbers. And internally we have a tuple of 12 numbers that are then multiplied together. Okay. If you find the tricky, just rewatch the video and play with it a bit. It's not too hard, really. It's the same concept as above when we talked about packing and unpacking. Now it's just in the context of functions. So why do you, why should you care about it? Why should you learn about that? Well, many functions, if you think about it, you don't know how many arguments a function should take, right? So naturally a function that does something with numbers may take one number or three numbers as an argument. And oftentimes it is easier to, to design a function so that it can just handle as many arguments as we want, okay? And that is just Python's way of doing that. And so you oftentimes, when you read code written by more experienced Python developers, you see these star arcs all the time. And just note within the function we are packing all the arguments in the arcs tuple. And when we call the function here, in this regard, we are going to unpack all the, all the numbers, right? This would be the same as if we manually did the following. Manually we simply go ahead and type all the numbers in there just like that. This should give us the same result. However, the unpacking is done for us by the star syntax, okay? So let me repeat what we learned in this video. So we started with a list as an example. And by having more than one variable on the left-hand side, we can have, we can unpack a list into variables. If the numbers, the number of elements on the right-hand side in the list and the number of variables on the left-hand side does not match, what you can do is you can use the star syntax here for packing. So this here is packing, okay? And yeah, and maybe let me show you another nice use case. So let's assume I have a variable a, which is zero, and I have a variable b, which is one. Let's say I want to flip the two variables. How can I do that? I can do packing and unpacking at the same time. So what I could do is I could say a, b will be set to the result of b, a. And if I now go ahead and look at a, it's going to be one. And if I go to look at b, it's going to be zero. So the values have flipped. So this is the same idea. So oftentimes you also see that if you want to flip the values of two variables kind of. When we talked about the iterative or the looping version of the Fibonacci numbers, not a Fibonacci number of the factorial numbers, then it is actually cool to put that in, right? And I think I did that in the video actually. So this is all packing and unpacking. And with for loops, we have done that before without knowing it, without calling it what it is and doing it with in the context of function cause, this is now new, but it's also not really new because now that you know what is packing and unpacking, well, you can just simply apply it in many, many different positions, right? So that is a nice thing to know. It makes writing code a bit nicer. And yeah, so learn about that. And in the next video, we are going to talk about some other things we can achieve using tuples. So I see you then.