 In this video, we are going to learn about another data type that we have not seen before, at least not explicitly. So we are still in the chapter 7 on sequences, on sequential data. So therefore, the data type we are going to learn about now is very much comparable to the list data type, but also in many ways comparable to the string data type. So let's go ahead and introduce a data type called tuples, or the tuple. So the tuple data type is very much like a list. And indeed, I would actually go ahead and let's give it a nice header here, where I summarize or where I give you the executive summary of the tuple data type. So tuples are like immutable lists. That for now is the main idea that you need to understand from this video. So let's first see how we can create a tuple. So just like we can create a numbers list with the numbers from let's say 1 to 12, using the bracket notation, like that, 10, 11 and 12. That will create a list object. And now there is only one thing you need to understand to get to a tuple, which is very easy. Simply remove the brackets, just like that. That's it. And now if we look at numbers, we see numbers with a parentheses, a pair of parentheses. And if we ask Python what is the type of numbers, Python tells us it's a tuple. So where do these parentheses come from? Well, tuples, when talking about the mass notation, would probably be written with parentheses and therefore you can also write them with parentheses in Python. Same outcome as before, but the tuples, the parentheses are not needed, right? So I personally, I always leave the parentheses in just to make it look like a tuple in mass notation, but some people just don't use the parentheses. Depends on what you prefer. Again, I usually write the parentheses in. So a couple of things when creating tuples. So first of all, tuples, let's say if you wanted to create an empty tuple, then there's only one way to do that. And the way to do that is to go ahead and write simply parentheses. So if I go ahead and maybe write that or store that in a variable called empty, and we ask Python what is the type of empty, then the type is going to be tuple. So now an empty tuple is often not very useful because as you can get from the header, it is an immutable data type. So in other words, if you start with an empty list, then you can at least append some data in it. But if you start with an empty tuple, there's basically nothing you can do with it, but sometimes you will encounter them and that is how you could create one. Alternatively, what you could do is you could use of course the tuple constructor. So let's say we go ahead and let's maybe give it a string, the tuple constructor, we give it a string and we will simply say lorem ipsum. And just like the list constructor would give us a list with elements where each element is a one character string, the tuple constructor does the same. So we get back a tuple where each element is a one character string. So sometimes you use that. So what is a nice way to use a tuple constructor? Well, another nice way which I personally often use is let's say you are given a list of data, let's say the list with the numbers 1, 2, 3, and you want to convert that into a tuple. Well, simply put the list inside the tuple constructor. And here you also see as a reminder that both strings and lists here share one property, which is the property of being iterable and size. It's two properties actually, so sized iterable. So we can loop over them and there is an end, the number of elements is finite. And these two properties are enough so that the tuple constructor can construct a tuple out of it. So it doesn't matter if I give the tuple constructor a list or a string, the only thing that matters is really that the properties are there, right? Any sequence can be used here. Okay, so let's go ahead. So what can we do with the tuple? So what we can do is the following. You can first of all check all the four properties. So let's say the four sequence properties. Four sequence properties are first the container property. So let's check if the number 0 is in numbers and it is not, but it is not the force that is important here, the answer. The important thing is that we don't get a type error, right? So we saw that I saw in one of the videos and I think in the first video of chapter 7, I showed you if we use the int operator with, for example, an integer, then I get a type error. But here we don't get a type error so it works. The int operator does not complain. Therefore, the first property, which is the container property, is fulfilled. The second property, we call the sized property, which is any object that works with the built-in LAN function. So let's give numbers to LAN and of course it works. So that property is called the sized property. And then, of course, we can loop over numbers. So for number in numbers, print number maybe to the power of 2 and let's print that on one line, it works. And last but not least, let's put here the iterable property, that is the formal name. And last but not least, the fourth property is, of course, the reversible property. So any sequence is always reversible, reversible, not. And then we loop over the numbers in reverse order. So these four properties are always there for sequencers. And as I said in the beginning of this video, tuples are just sequencers. So what else can we do? Well, anything that regards indexing and slicing also works. So let's say I want to maybe get the fourth element, which would have index 3. I can just obtain it. If I want to get a slice, I can also do that. So if I want to get all the elements, except for the first and the last, what I could do is I could say 1 positive 1 colon negative 1. So go from the second element, so the index 1, including to the last element with the index negative 1 excluded. And this will give me the 10 elements in the middle without the first and the last. And we see by the notation with the parentheses that we get back a tuple again. And that makes sense. If I slide into a string, I get back a string. If I slide into a list, I get back a list. If I slide into a tuple, I get back a tuple. So slicing is independent of the data type, of the concrete data type. It is more a consequence of the abstract behaviors of the data type. Now, one thing that does not work, of course, is I could not go ahead and let's say, for the first element, I want to replace that with the number 99. So I assigned the number 99 to the first element in the tuple. This does not work. And here it says item assignment is not supported. And that is basically telling you that the tuple data type is immutable, right? So as I said, tuples are like immutable lists. Well, here you got the immutability. Okay. So let's also quickly mention, I'm not going to write that here, but many of the list methods, especially in particular only the list methods that we have reviewed in a previous video, that do not change the list object itself, can be used here. So for example, I give you one example. If I use the count method, because the count method simply counts the number of objects with a certain value in it. So let's say, if I want to count the number of tens in the numbers list, I get back one because there's only one number 10 in it. So count works on a string. It works on a list. It works on a tuple. And all of those have in common that they are sequences. And the count method does not change the value. It does not change the references inside the tuple. So therefore, it is a read only method if you so want. And therefore it works for all the different data types. However, let's say if I want to remove the last element, let's say with the pop method, the pop method that we know from list objects does not exist for tuples. We get an attribute error. The attribute, the tuple object does not have an attribute called pop. Okay. It makes sense because pop would indeed change the underlying list object. And as tuples are immutable, it simply doesn't work, right? We can, I mean, popping a value of, popping the last element of a tuple would basically change the tuple and this is not allowed. It's immutable. Other stuff that we could briefly say, of course, if I say, if I multiply the numbers tuple by two, I get back a bigger tuple with all the elements repeated, just like for, as we did for list concatenation. So this would probably be called tuple concatenation, although I have never heard this term, but this is really what it is because this basically creates a new tuple with just twice as many elements. So this does not change the actual tuple. Other operators that would also work is the plus, of course, all the relational operators when I did the, in the video where I talked about list operations, about list comparisons, everything that you learned there also works for tuples. So that is what I mean when I say tuples are like immutable lists. They can basically do anything that is a read-only operation or a method on a list object, okay? And now why would you want to use a tuple? So when I started with Python, I rarely used tuples. I always used lists all the time. But then the problem is, as we saw in the previous video, when we pass in a list object as an argument to a function, then we should better not change it inside the function because then otherwise, we would have the overall outcome that a function is given some input, it gives back some output, and also the input changes. So in addition to getting an output from some input, the input also changed, and we don't want that usually. So we usually want pure functions. And one trick that you can apply to force yourselves to write pure functions is by simply using tuples all the time instead of lists. So whenever you want to use a list in Python, simply go ahead and use a tuple, and at some point, maybe you realize that you need to make a change. And then later on, you may want to replace the tuple with a list because if you know that the data you're working with needs to be changed, you need to work with a list. You cannot do that with a tuple. If you need mutability, you cannot work with tuples. So in other words, what I did is when I started with Python, for me the default was the default data type for modeling sequential data was the list data type, and the tuple I did not really know about. But the better way to view things is to use the tuple data type as the default data type, and then only if you need mutability, switch to the list data type. So preferably use tuples whenever you can, and only lists whenever you must. That would probably be a better approach. Although I haven't heard about this best practice so far, but I think it's a good best practice because it forces yourself to write pure functions, which is a lot better in the long run. Okay, so that is the tuple data type, the first video about the tuple data type. I will show you in a couple of more videos what else there is to know about tuples, but these are the very basics. And again, tuples are like immutable lists, that is the main outcome. And there will be another video where we talk about named tuples, so-called named tuples, because tuples are also sometimes viewed as records of data sets or records in a big table of data. So there will be a second view of what the tuple can be, but for now the view that you have is a tuple is an immutable list, and then there will be another few in a couple of videos from now. Okay, so I will see you in the next video. And yeah, see you soon.