- [Instructor] Now that we've talked about lists
in more detail, let's take another look at tuples.
So for that purpose, we're going to go ahead
and use an interactive iPython section.
And first let's talk about creating tuples
a little bit more.
Now previously we demonstrated that you can
create a tuple using a comma separated list
of items in parenthesis.
It turns out the parenthesis are not required
with a couple of exceptions,
one of which is when you create an empty tuple.
So if you want a tuple of no elements at any
given time, then you simply use an empty set of parenthesis,
and when you evaluate any tuple,
it's going to display that tuple's contents
in parenthesis, so as you can see here we get an
empty set of parenthesis for the empty tuple.
And we can also confirm that it has no elements.
All we have to do is use the len function to do that,
and we can see indeed that the number
of elements is zero.
Now let's take that student tuple variable
and let's assign it a completely new tuple.
Actually you know what, let's do it without parenthesis
this time just so you can see that the parenthesis
are not required.
So let's say we have somebody named John Green,
and we'll assume since this is a student
that we're going to have a grade point average
associated with that student as well.
What makes this a tuple is not parenthesis,
in fact we have no parenthesis here,
it's the commas that separate the individual values.
Tuples are commonly use to group together
related pieces of data,
and in the case of a student,
this might be the first name, last name,
and grade point average of a given student.
Now once we have that tuple,
we can go ahead and evaluate it and see the contents,
but notice when Python outputs the tuple,
it always uses those parenthesis even though
they're not required to create the tuple in the first place.
Let me go ahead and recall the lens snippet from up above,
and now we have this student tuple variable
referring to a completely new separate tuple object.
I can't modify the existing one,
they're immutable, so anytime you assign
to a variable that previously was referring to a tuple,
another tuple, you're just replacing the one that was there,
aiming it at a new object.
But now we can see that based on the updated object,
we have a length of three for that particular tuple.
Now the parenthesis are not required, but we do
recommend using them.
So let's say we want to create another student tuple
and for this other student,
let's put the names and everything in parenthesis.
So let's do something like Mary and Red,
and we'll give the same grade point average for now.
So here we have a completely new tuple that we just
created, this time we used parenthesis,
and of course if we then go and evaluate that,
you still see those parenthesis
in the string representation.
Now, sometimes you'll create tuples that have only
one element, and you may be tempted to simply
provide an individual value to represent that tuple.
Let's create a variable, we'll call it a singleton tuple,
and let's say we wanted to just put the string red
in there.
If I complete this assignment,
what I have is a variable referring to a string.
So you might say well wait, all right,
let's put it in parenthesis.
Well what I'd have in this case is still
a variable referring to a string because
the parenthesis are not what defines a tuple.
Commas are what defines a tuple.
So if you really want to create a tuple
with only one element in it,
you're going to put that element followed by a comma.
And because that's kind of a strange notation
to most programmers new to python,
I recommend also putting that in parenthesis as well
to further emphasize the fact that you're creating
a tuple and group those items together.
So the way I can tell that this is a tuple
versus just an individual string is if the parenthesis
get displayed around the contents.
So if I now go and evaluate that tuple,
we can see that indeed the parenthesis
are displayed and not only that,
in the case of a singleton tuple,
it also displays the trailing comma
to indicate that indeed, it is a tuple.
So now that we've shown how to create a few tuples,
let's now start talking about accessing tuple elements.
Now turns out that the square brackets we used
to access the elements of a list can also be used
to access the elements of any sequenced data structure.
So that could be a string,
and in fact we demonstrated earlier that you can use
the square brackets to access an individual character
in the string, and it can be a tuple as well,
and that's what we'd like to take a look at here.
Now to save me a little bit of typing time,
let me go ahead and copy and paste here a time tuple,
and let's assume these represent hours, minutes,
and seconds, and what we would like to do first
is just display that so we can see the contents,
and make sure that it was initialized correctly.
And let's assume we'd like to use each of those
three values in a calculation.
So let's say we want to calculate the total number
of seconds based on the current time.
So here we have an expression that will do that,
where we use time tuple sub zero to access
the element at index number zero within the tuple.
We're going to assume that's the hours
and multiply that by 3600 for the total number
of seconds in a hour.
Then we're going to add to that the result of the next
expression which uses time tuple sub one to get
the next element in the tuple,
and then finally we'll add to that the seconds
which is the last element in the tuple,
the element index number two.
Now when we evaluate that, we can see the total
of all of those elements.
So you can always use the elements within a tuple
by the tuple name, a set of square brackets,
and an index number.
In the next section, we'll actually show another way
to access the elements of a tuple.
Again, we'll revisit the concept called unpacking
which we demonstrated briefly in the functions lesson.
So now let's talk a little bit about operations
that appear to modify tuples.
So once again, let me go ahead and do some copying
and pasting here to save some typing time.
Tuple one is going to be a tuple containing three integers,
10, 20, and 30.
And let's go and create a second variable,
tuple two, and we'll assign it tuple one.
So first of all, this is a reference assignment.
The variable tuple one is not the object containing
10, 20, and 30, it is a reference to that object.
So what I'm doing here is taking that reference
and placing it into tuple two.
As a result of that snippet that I'm now executing,
both of these variables refer to the same tuple object
in memory, and recall that you can actually check that
with the ID function that's built into Python.
Now of course if I evaluate tuple two,
I can see that it appears to have the same contents
as what we assigned to tuple one up above,
and that's again because they are in fact
the same object.
So what about an expression like this.
Let's say we want to do tuple one plus equals,
and we want to add to the end of that tuple, 40 and 50.
Now tuples are immutable, so when you see an expression
like this with an immutable object referred
to on the left hand side,
what's really going to happen here is Python is going
to create an entirely new tuple object containing
all of the values from whatever object tuple one
refers to and these new values in the tuple on
the right hand side of the plus equals operator.
Then we'll have that new objects reference
get assigned back to tuple one,
replacing the original object's reference.
So tuple one currently refers to 10, 20, and 30,
but it's going to be reaimed at a different object
as a result of executing that statement.
Now if you simply evaluate tuple one,
you can see that all the elements are there,
but you really can't tell that it's a separate object
unless you start playing with the ID function
once again, to check what the ID's of the objects are
before and after the operation.
And I'll leave that up to you to try out as an exercise.
It's one of the great things about the interactive
iPython environment, that you can just fiddle around
like that and learn more.
Now did this modification modify tuple two?
Well, let's check that.
So we can evaluate tuple two and see that it's still
aimed at the original tuple object.
Now if the left hand side is a mutable object
like a list, then the plus equals operation
works a little bit different.
So let's say I have numbers as a list
and we'll put some values in there.
So there's our list numbers,
and let's say we want to modify numbers
by adding to the end of it with the plus equals
operator, a tuple of additional elements.
Let's say we want to add on six and seven.
So again, we saw this with lists in the proceeding video.
When the left hand side is a list,
the right hand side has to be some sort of iterable
object, some sort of sequence typically,
and that could be another list,
it could be a tuple, it could be a string,
it can be anything that is capable of being
iterated over one element at a time.
And each individual element will be appended to the end
of the list up above.
So we can go ahead and execute that,
and evaluate numbers to see that indeed,
six and seven were appended to the end of that list.
Now the last thing I'd like to talk about
in this video is the fact that tuples,
though they are immutable themselves,
are capable of storing mutable objects.
So I'm gonna go ahead and copy and paste
a tuple in here, called student tuple.
This particular tuple has three elements.
Amanda and blue are strings representing
a first name and a last name,
and this last element is a list object
containing three grades that of course,
probably belong to Amanda Blue.
So we've now created this student tuple object,
and we can access the elements within the student tuple
using the square brackets operators.
Now if I use a square bracket
and I say student tuple sub two,
well Amanda is element zero.
Blue is element one, and this last element,
element two, is a list object.
Well if it's a list object,
I can use a second set of square brackets in this
and I can go ahead and say let's say this grade was wrong,
75, so I want to fix it.
I can make it 85, so this is going to go to the
third element of the tuple,
which happens to be a list,
then it's going to access element number one
within that list which is the second element here,
and we're going to replace that value with 85.
So the list operation of modifying the contents
of one element in that list seems to have worked
because we didn't get an error message here.
So to prove that, we can go ahead and evaluate
student tuple and see that indeed,
we were able to modify that object because
the object that this element refers to
is a mutable, modifiable object.