SchoolWhool
Quizzes and saved progress, freeSign in freeSign in

Python 3.2Free video13 minLesson 2 of 6 in Module 3

Tuples

Use fixed-size immutable records, and unpack them.

Free sample. Everything in this module opens with a free account.

Watch or read the lesson: Tuples

01Immutable sequences: a coordinate as a list and as a tuple

In the previous lesson, you learned how to work with Python lists. The most important thing about a list is that you can change it whenever you need to. But what if you have a group of values that you do not want to change?

Think about a GPS coordinate. Take New York City: its approximate coordinates are 40.7128 and -74.006. The first number is the latitude, and the second is the longitude. These two values belong together, and their positions have a specific meaning. If you swap them, you are no longer describing the same location.

A coordinate in a list

Start by storing the coordinate in a list called location. It holds two values, the latitude and the longitude, and everything you learned in the previous lesson works on it. You can read the values, you can replace them, and you can even add more values. For example, try location.append(920):

location = [40.7128, -74.006]
location.append(920)
location
[40.7128, -74.006, 920]

This runs. Python simply adds 920 to the end of the list, so the coordinate now contains three values instead of two. But that is not the structure this example needs. You wanted exactly two values, one latitude and one longitude, and you do not want someone accidentally adding or removing elements. So is there a way to store these values together while preventing that kind of modification?

A coordinate in a tuple

Create the same coordinate again, but this time use round brackets instead of square brackets, and call it point:

point = (40.7128, -74.006)
point
(40.7128, -74.006)
Predict first

Now try changing the latitude with point[0] = 13.0. What do you think happens? Think it through before reading on.

I have a guess. Show meHide the answer
point[0] = 13.0
TypeError: 'tuple' object does not support item assignment

You get a TypeError. Python tells you that a tuple does not support item assignment. So unlike the list, you cannot replace an element inside this tuple, and point still holds the original two values.

Two questions

That is the main idea this lesson explores, through two questions. What exactly is a tuple? And how do you work with values you are not allowed to change?

02Creating and reading a tuple

Start with the first question. If you check the type of point with type(), Python tells you it is a tuple:

type(point)
tuple

A tupleKey termAn ordered sequence of values, written with commas, that can not be changed: (12.9716, 77.5946). is an ordered sequence of values, just like a list. But there is one important difference: a tuple is immutableKey termAn object that can not be changed after it is created: a tuple, a string, a number.. You met that word in the previous lesson. Immutable means the object cannot be changed after it is created. So once you have created a tuple:

  • you cannot replace one of its elements,
  • you cannot add another element,
  • and you cannot remove an existing one.

The structure of the tuple stays fixed.

There is one detail to keep in mind. A tuple's own elements cannot be replaced, but if one of those elements refers to a mutable object, such as a list, that object can still be modified. So immutability applies to the tuple's own structure. It does not automatically make every object inside it immutable.

Indexing

Here is the good news: almost everything you learned about reading values from lists also works with tuples. point[0] gives you the first element, the latitude:

point[0]
40.7128

point[-1] gives you the last element:

point[-1]
-74.006

And len(point) tells you that the tuple contains two elements:

len(point)
2

So indexing works exactly the way you would expect.

Slicing

Slicing works too. Suppose you want to represent a date. Create a tuple called today and store three values inside it: the year, the month and the day. For this example, use 2026, 9 and 23. Then today[0] gives you the year:

today = (2026, 9, 23)
today[0]
2026

Write today[1:], and Python gives you the month and the day:

today[1:]
(9, 23)

Notice something interesting. When you slice a list, you get a new list. When you slice a tuple, you get a tuple. If you check the type of that sliced result, Python confirms it:

type(today[1:])
tuple

03Immutability and rebinding a name

Immutability means more than not being able to replace an element. Go back to point, and try append:

point.append(920)
AttributeError: 'tuple' object has no attribute 'append'

This time Python raises an AttributeError, because tuples do not have an append method. That makes sense: append would change the number of elements, and tuples do not allow that. The same goes for the other list methods that modify the sequence, like insert, remove and sort. Tuples do not provide those methods.

Rebinding a name

Here is a question. If tuples are immutable, does that mean you can never change the value of a variable that refers to a tuple?

No. Right now, point refers to the coordinates of New York. Suppose you want it to refer to Los Angeles instead:

point = (34.0522, -118.2437)
point
(34.0522, -118.2437)

That works perfectly fine, with no error. But why? Didn't you just learn that tuples cannot be changed?

The important distinction is that you are not changing the original tuple. You are creating another tuple and assigning it to the name point. So point now refers to a different object. This is the same idea you met in the variables lesson: assignment binds a name to an object, and rebinding a name points it at a new object without changing the old one.

04Tuple syntax: the comma, one item tuples and the trailing comma bug

Here is something about tuples that might surprise you: it is not actually the round brackets that make something a tuple.

Brackets alone group an expression

Predict first

Suppose you write just the string "Mia" inside round brackets. What do you think its type is? Is it a string, or a tuple containing one string? Think it through before reading on.

I have a guess. Show meHide the answer
type(("Mia"))
str

Python tells you it is a string, not a tuple. Why? Because round brackets around a single value simply group that expression, just like parentheses in arithmetic.

The comma makes the tuple

So how do you create a tuple with only one element? You need a comma. With a comma after "Mia", the expression is a tuple:

type(("Mia",))
tuple

And it contains one element, the string "Mia":

len(("Mia",))
1

So here is the important rule: in most ordinary tuple expressions, it is the comma that creates the tuple, not the round brackets. In fact, you can create a tuple without writing round brackets at all:

point = 40.7128, -74.006
point
(40.7128, -74.006)

Parentheses are still useful. They make the structure easier to read, and in some situations they are required. For example, an empty tuple is written as ():

type(())
tuple

But for an ordinary tuple of two or more values, the commas are what matter.

The trailing comma bug

This leads to a mistake that is surprisingly easy to make. Suppose you are working with a restaurant bill, and you write total = 26.75,. Notice the comma at the end. Maybe you typed it by accident.

total = 26.75,
total
(26.75,)

total is not a float anymore. It is a tuple containing one float:

type(total)
tuple

Python does not raise an error when you create it, because it is perfectly valid syntax. But later, suppose you try to add one to this total:

total + 1
TypeError: can only concatenate tuple (not "int") to tuple

Now you get a TypeError, because Python cannot concatenate a tuple with an integer. So if you ever see an error mentioning a tuple when you thought you were working with a number, check whether you accidentally left a comma after the value. That single comma can completely change the type of your variable.

So far

So far, you have learned that a tuple is an ordered, immutable sequence. You can access its elements using indices, and you can slice it, but you cannot change the tuple's own elements after creating it.

Now for the second question: how do you work with the values inside a tuple?

05Packing and unpacking

Return to the GPS coordinate. point contains the latitude and longitude of New York. You could access the latitude with point[0] and the longitude with point[1]. That works. But imagine you are using these values throughout a larger program. Every time you write point[0] or point[1], you have to remember which position represents which coordinate. Wouldn't it be easier to give them meaningful names?

Tuple unpacking

Python lets you do exactly that, using something called unpacking. Write this statement:

lat, lon = point
print(lat)
print(lon)
40.7128
-74.006

Here is what happens. Python takes the first element from point and binds it to lat. Then it takes the second element and binds it to lon. So lat holds the first element, lon holds the second, and you can use those names directly.

This is called tuple unpacking: taking the values from a tuple and assigning them to separate names.

Too many values

Predict first

What if the number of names does not match the number of values? Create another tuple called place. This time it contains three values: latitude, longitude and altitude, using an altitude of 920 meters for this example. Now suppose you write a statement with just two names, lat, lon = place. What do you think happens? Will Python ignore the third value, or will it raise an error? Think it through before reading on.

I have a guess. Show meHide the answer
place = (40.7128, -74.006, 920)
lat, lon = place
ValueError: too many values to unpack (expected 2)

You get a ValueError. Python tells you there are too many values to unpack: it expected two, but the tuple contains three. So with ordinary unpacking like this, the number of names must match the number of values.

If you want all three values, write three names:

lat, lon, altitude = place
print(lat, lon, altitude)
40.7128 -74.006 920

Now it works. Each name receives the corresponding value.

Not enough values

The same rule applies in the other direction. Suppose you try to unpack the original two-value point into three names:

lat, lon, altitude = point
ValueError: not enough values to unpack (expected 3, got 2)

Now Python raises a ValueError saying there are not enough values to unpack, because there are three names but only two values.

Packing

There is another related concept, packingKey termCollecting several values, separated by commas, into one tuple: point = 12.9716, 77.5946., and you have already seen it, even without that name. When you write several values separated by commas, Python collects them into a tuple. In this statement, you are packing two values into a tuple:

point = 40.7128, -74.006
point
(40.7128, -74.006)

And in this statement, you are unpacking that same tuple into the names lat and lon:

lat, lon = point
print(lat)
print(lon)
40.7128
-74.006

06Choosing lists and tuples for meaningful positions

Now that you have explored tuples, here is a practical question: when should you use a tuple instead of a list? Think about what your data represents.

If you are working with a collection that needs to grow or change, a list is usually the natural choice. Take a shopping cart. You might add items, remove items or replace them, and lists are designed for exactly that.

But if you are representing a fixed group of values where each position has a particular meaning, a tuple can be a good choice. Take a GPS coordinate again. The positions are meaningful, and you do not normally want to add or remove elements from that structure.

07Recap and challenge: tuples, packing and unpacking

This lesson started with a GPS coordinate stored in a list. Then you stored the same coordinate in a tuple, and when you tried to replace an element, Python raised a TypeError. That is the key difference between the two: lists are mutable, and tuples are immutable.

You also learned that tuples support indexing and slicing, and that a slice of a tuple is another tuple. Then you saw that it is the comma that creates a tuple in ordinary tuple expressions, which is why a one-element tuple needs a trailing comma, and why a stray comma after a number turns it into a tuple.

After that, you explored packing and unpacking. Packing groups values into a tuple, and unpacking assigns the values from a sequence to separate names.

Your challenge

Create a small report about four cities.

  1. Represent each city as a tuple containing three values: its name, its latitude and its longitude.
  2. Store all four city tuples inside a list.
  3. Write a for loop that unpacks each tuple directly in the loop header, and print one line per city, with the city's name and both coordinates formatted to two decimal places.
  4. As a second challenge, find the city that is furthest north. Latitude tells you how far north or south a location is, so the city with the largest latitude is the northernmost. Solve it with the loops and comparisons you have already learned.

Once that works, think about why a tuple makes sense for each coordinate.

In the next lesson, you will look at another collection type.