Hello, and welcome to the eleventh episode of the Software Carpentry lecture on Python. This episode introduces Python's "other" kind of sequence data type.
As we saw a few episodes ago, a list is a mutable sequence of values, which can be of any type.
A tuple is simply an immutable sequence of heterogeneous values.
I.e., a list whose entries can't be changed after its creation.
At first or even second glance, it may seem strange to have tuples in the language—why provide a less general kind of collection?
The full explanation will have to wait for the lecture on sets and dictionaries.
But tuples allow us to do a few useful things even before we get that far.
In Python, we create tuples using parentheses
() instead of square brackets
We still index them with square brackets, though, because everything in Python that's indexed uses square brackets.
For example, here's a tuple containing the first four prime numbers. Just as with a list,
primes is its first element, and
primes[-1] is its last.
The empty tuple is written as, well, empty parentheses, and has a length of 0.
If we want to create a tuple of just one value, though, we have to put a comma after that value and before the closing parenthesis. It looks a little odd…
(5) would be ambiguous: mathematically, it's the same as
This trailing comma is easy to forget, and is one of Python's few syntactic warts.
The good news is, we don't need the parentheses if it's clear from context that we're constructing a tuple.
For example, we can create our tuple of primes just by putting commas between the four values, as shown here.
The neat thing is, if we put a tuple of variables on the left side of an assignment, we can assign multiple values at once.
For example, this statement sets the values of
right all in one go.
We can check that it worked by printing those variables out.
But remember: with great power comes great responsibility. Initializing thirty-odd variables at once this way is probably not going to make your programs more readable…
This same trick—tuple-to-tuple assignment—allows functions to return several values at once.
For example, here's a function called
bounds that returns the lowest and highest elements of its parameter
values at the same time.
Sure enough, it returns a two-element tuple.
And if we assign that tuple to a pair of variables, Python unpacks the two values and copies them into the variables in the right order.
Functions sometimes use this technique to return a success or failure flag along with their actual result, which is only valid if the flag indicated success.
Here, for example,
read_if_available returns either
True and a list of data values, or
False and an empty list.
Its caller can capture both values at once, then check the first to learn whether the second is meaningful or not.
We'll meet a better way to do this kind of thing in the lecture on testing.
Multiple-valued assignment is also a quick way to swap variables' values.
right to 0 and 10 respectively.
And then assign
Sure enough, when we're done, Python has swapped their values.
There's no magic here: behind the scenes, Python is creating a temporary variable to hold onto one value while it copies the other.
If we draw what's in memory at the start,
left refers to 0 and
right refers to 10.
Python creates a temporary variable (probably not actually named
_tmp_, but that doesn't matter)…
left's pointer to 0 into it.
It then copies
…and throws away the temporary variable, all behind the programmer's back.
Multi-valued assignment is also a quick and easy way to unpack the elements of lists.
colors holds the strings
…and we assign
colors to a trio of variables called
…then sure enough,
left has been assigned
middle has been assigned
right has been assigned
This only works if the number of variables on the left to "catch" values is the same as the number of values in the list.
Unpacking is often used to simplify loops.
For example, suppose we have a list of pairs of numbers.
We could add the values in each pair like this…
…but it's not particularly readable.
Here's a better way: the
for loop gives us the pairs one by one, and when we assign each pair to the two variables
high, Python automatically unpacks the pair's values for us.
We'll use this technique a lot in the lectures that follow.
To make life even easier, Python has a built-in function called
enumerate that takes a sequence (i.e., a list, tuple, or string) as input, and produces (index, value) pairs—just right for looping.
This bit of code uses
enumerate to loop through our list of colors, printing each value and its index.
The output is pretty much what you'd expect.
And this is tidier and more efficient than the
range(len(list)) idiom shown a few episodes ago.