Chapter 20: Python: List and Tuple
The day before sports day, the physical education teacher gives you a job. Every student in your class will take part in the long jump, and you have to note down how far each one jumps. There are thirty students.
You would never draw thirty separate boxes on the page and label them Box 1, Box 2, Box 3, all the way to Box 30. You would rule one column, write the names one below the other, and put each reading beside its name. One page. One column. Thirty readings, still in order, and you can always point to the fifth one.
A program faces exactly the same problem. Until now, each name you created in Python held a single value, and a single value is fine for a single reading. Thirty readings need something else — one name that holds many values, kept in a fixed order.
There is a second half to the job as well. The list of events on the sports day card was decided weeks ago and must not be altered by anybody. Python has a way of storing that too. See Fig. 20.0-1.
Diagram
Fig. 20.0-1 – two labelled containers side by side. Left container drawn with square brackets [ ] and an open lid, holding four cards reading 3.2, 2.9, 3.5, 3.1, with small index labels 0, 1, 2, 3 below the cards, and two curved arrows showing a card being added and a card being taken out. Right container drawn with round brackets ( ) and a sealed lid, holding four cards reading 100 m, Long Jump, Relay, March Past, with the same index labels 0, 1, 2, 3 below, and a crossed-out arrow showing that no card can be added or taken out. Caption strip under the left container: “can be changed after it is made”; under the right container: “fixed once it is made”
This chapter answers all five of these questions.
20.1 Holding Many Values in One Place
A variable is a name that a program uses to remember something. You write age = 15, and from that moment the name age stands for the value 15. If you later write age = 16, the old value is gone and the name holds the new one. One name, one value at a time.
That is enough for many small programs. It stops being enough the moment a program has to remember a set of things that belong together — the jump distances of a whole class, the names of the students in a group, the price of every item on a shop bill.
Doing it the long way
Suppose you measure three long jumps and want their total. With ordinary variables it can be done, and it is worth seeing exactly how it looks.
The program runs, and for three jumps it is perfectly reasonable. Now imagine the same idea for thirty students. You would have to invent thirty names, type thirty assignment lines, and write an addition with thirty terms in it. Miss one name and the total is quietly wrong.
There is a worse problem hiding behind the typing. A computer is good at repeating an instruction, but it can only repeat an instruction that stays the same each time. jump1, jump2 and jump3 are three different names, so a loop has no way to walk through them. The values are related in your head, but not in the program.
One name, many values
What a program needs is a single name that holds many values at once, kept in the order you put them in, so that the program can ask for the first value, the second value, or every value in turn. Fig. 20.1-1 shows the difference.
Diagram
Fig. 20.1-1 – two rows compared. Top row labelled “one name, one value”: a single box labelled age holding the value 15. Bottom row labelled “one name, many values”: a single label jumps with an arrow pointing to a strip of four joined boxes holding 320, 290, 350, 310 in that order, with the numbers 0, 1, 2, 3 written under the boxes. A curved arrow from the label to the strip is marked “the whole strip has one name”
Once the values sit together under one name, everything becomes easier. The program can add them all up, find the largest, sort them, count them, or go through them one by one — without knowing in advance how many there are.
Python gives you two ways of doing this. One of them lets you change the values afterwards; the other locks them once they are made. The rest of this chapter is about both.
20.2 Introduction to Lists
The single name that holds many values is called a list. A list keeps its values one after another, in the order you put them, and it lets you change them afterwards — add a new one, remove one, or replace one.
Each value stored inside a list is called an element of the list. The four jump distances 320, 290, 350 and 310 would be four elements of one list.
Think of the attendance register in your class. It is one book, the names sit in a settled order, and the teacher can still add a new student at the end of the year or strike one off. That is exactly how a list behaves.
20.2.1 Creating a List
To create a list, write the values inside square brackets [ and ], separated by commas, and give the whole thing a name.
The values do not all have to be of the same kind. A list can hold whole numbers, decimal numbers, text, or a mixture of them. A list with nothing in it is written as an empty pair of brackets, and that is useful when values will only be added later while the program runs.
Notice two small things in the output. Python prints the brackets and commas back to you, so you can see the shape of the list at a glance. It also prints text values inside quotes, which is its way of showing that 320 and "320" would not be the same element.
20.2.2 How a List Behaves
Four things about a list are worth fixing in your mind, because everything you do later in this chapter depends on them.
Order. The elements stay in the order you typed them. Python does not tidy them or sort them by itself. If the first jump you recorded was 320, then 320 stays first until you deliberately move it.
Position. Because the order is settled, every element has a definite place in the list — first, second, third — and Python lets you reach any one of them directly, without walking past the others. Section 20.3 shows how.
Repeats allowed. The same value may appear more than once. Two students can jump exactly 320 cm, and both readings belong in the list.
Changeable. A list is mutable, which means its contents can be changed after it has been created. You can replace an element, add new ones, or remove some. The name stays the same; what it holds does not have to.
The two reds are two separate elements. Python has no reason to merge them or to move green out of the way.
Being mutable is what makes a list the natural choice for data that is still being collected — marks as they are entered, items as they are added to a bill, readings as they arrive from a sensor. A list also grows and shrinks on its own. You never have to say in advance how many elements it will hold, unlike some other languages where the size must be fixed before use.
That last point is not a small one, and it is the reason Python offers a second, locked-up way of storing many values. You will meet it in 20.5.
20.3 Accessing the Elements of a List
Putting values into a list is only half the job. A program must also be able to take them out again — sometimes one particular value, sometimes a whole stretch of them.
20.3.1 Reaching One Element by Its Index
Every element of a list has a number that says where it sits. That number is called its index. Python counts the index from 0, so the first element has index 0, the second has index 1, and so on.
Counting from 0 looks odd at first. It becomes sensible if you read the index as how far this element is from the start rather than which one it is. The first element is at the start already, so it is 0 steps away.
To reach an element, write the name of the list followed by the index in square brackets. Python also accepts negative index numbers, which count backwards from the end: -1 is the last element, -2 the one before it. That saves you from working out the length of the list every time you want the final value. See Fig. 20.3-1.
Diagram
Fig. 20.3-1 – a horizontal strip of four joined boxes holding 320, 290, 350, 310, labelled jumps on the left. Above the boxes, the index numbers 0, 1, 2, 3 with small downward arrows. Below the boxes, the negative index numbers -4, -3, -2, -1 with small upward arrows. A note at the right end reads “index 4 does not exist”
The third jump is jumps[2], not jumps[3], because the counting starts at 0. And jumps[-1] gives 310 without the program needing to know that the list has four elements in it.
20.3.2 Taking a Slice of a List
Sometimes one element is not what you want. You may need the first three marks, or everything from the fourth reading onwards. Taking a stretch of a list like this is called slicing.
A slice is written with two index numbers separated by a colon: marks[1:4]. The first number says where to start. The second number says where to stop — and Python stops just before it, so the element at that index is not included.
Either number may be left out. Leaving out the first means “from the very beginning”, and leaving out the second means “up to the very end”. A third number may be added, as in marks[::2], and it says how big a step to take — 2 means take every second element.
Look carefully at the first line of output. The slice marks[1:4] gives the elements at index 1, 2 and 3 — it stops before index 4, so the mark 90 is left out.
One more thing is worth knowing. A slice does not disturb the original list — Python builds a fresh list out of the chosen elements and hands that back. The list marks still holds all six marks after every one of those four lines has run.
20.4 Operations on a List
A list is useful because it does not stay still. Values can be put in, taken out, replaced, arranged in order and looked for. Python provides ready-made instructions for all of this, so you never have to write the fiddly work yourself.
Most of these instructions are methods. A method is an instruction that belongs to a particular value and is written after it with a dot, like subjects.append("English"). Read it as: take the list called subjects, and append to it.
20.4.1 Adding Elements
A class list of subjects grows when a new subject is offered. A shopping bill grows with every item scanned. Python gives three ways of adding to a list, and they differ in where the new element goes and how many elements arrive.
append()puts one new element at the end of the list.insert()puts one new element at a position you choose, and everything after it shifts along.extend()takes a whole second list and adds all of its elements to the end, one by one.
Follow the second line of output carefully. insert(1, "Hindi") places Hindi at index 1, so Science, which was at index 1, moves to index 2, and English moves from index 2 to index 3. Nothing is lost; everything after the new element simply shifts one place to the right.
Joining and repeating lists
Two lists can also be joined with the + sign, and a list can be repeated with the * sign. These do not change either of the original lists — they build a brand new list and hand it back.
The last line is the point of the example. After all that joining and repeating, group1 is untouched. If you want a list to actually change, use extend(); if you want a fresh list built out of two others, use +.
20.4.2 Changing and Removing Elements
An element can be replaced by writing its index on the left of an equals sign. This is the same square-bracket notation you used for reading an element, only now it is being written to.
For removing, Python offers three methods that suit three different situations.
remove()takes the value you want gone and deletes the first element that matches it.pop()takes the index you want gone, deletes that element, and hands the deleted value back so you can use it. With no index given, it removes the last element.clear()empties the list completely, leaving the name in place with nothing in it.
Notice that pop() did two jobs at once — it removed 45 from the list and gave that value to the variable first. remove() gives nothing back; it only deletes.
20.4.3 Sorting a List
Marks are usually entered in roll-number order, but a merit list needs them in order of value. Rearranging the elements of a list into order is called sorting, and sort() does it.
By default sort() arranges elements in ascending order — smallest first for numbers, alphabetical for text. Adding reverse=True inside the brackets arranges them the other way round. A separate method, reverse(), does something different: it simply flips the list end for end, whatever order it happens to be in.
Both sort() and reverse() rearrange the list itself. The old order is gone for good, so if you still need the original order, make a copy of the list before sorting.
One honest limitation: sorting works only when Python can compare the elements with one another. A list holding both numbers and text cannot be sorted, because there is no sensible answer to whether 45 comes before or after “Anita”, and the program stops with an error.
20.4.4 Searching in a List
Searching means answering one of two questions: is this value present at all? and where is it? The keyword in answers the first. The method index() answers the second, and count() tells you how many times the value occurs.
Before using them, it helps to know what Python is actually doing.
20.4.5 Counting and Summing with Built-in Functions
The last four instructions are not methods. They are ordinary functions, so the list goes inside the brackets rather than before a dot.
len()gives the number of elements in the list.min()gives the smallest element.max()gives the largest element.sum()adds up all the elements, and needs them all to be numbers.
Together, sum() and len() give you the average of a set of values without any counting by hand.
20.5 Introduction to Tuples
Not every set of values is meant to change. The order of events printed on a sports day card was settled weeks ago. The twelve months of the year are what they are. A set of subject codes handed to a school by the board is not for the school to edit.
If such values are kept in a list, nothing protects them. Any line anywhere in the program can append to that list or overwrite an element, and no warning is given. For values that are supposed to stay fixed, Python offers a second store called a tuple.
A tuple holds many values under one name and keeps them in order, exactly like a list. The one difference is that once a tuple has been made, it cannot be altered — no element can be replaced, added or removed.
20.5.1 Creating a Tuple
A tuple is written with round brackets ( and ) instead of square ones, with the values separated by commas.
Two small cases need care. A tuple with nothing in it is an empty pair of round brackets. A tuple with exactly one value must have a comma after that value, otherwise Python reads the brackets as ordinary brackets around a single value and no tuple is made at all.
Python prints the lone comma back to you in the third line. That comma is what makes single a tuple of one element rather than just the piece of text “Relay”.
The round brackets can in fact be left out altogether — point = 3, 4 makes a tuple of two values. Putting several values together like this is called packing. Keep the brackets while you are learning, though, because they make the tuple visible to anyone reading your program.
A tuple may also hold another tuple as one of its elements, which is handy when each item is itself a small group of related values.
20.5.2 How a Tuple Behaves
A tuple keeps order in exactly the way a list does. The first value you wrote stays first, repeats are allowed, and every element has a position that can be used to reach it.
What is different is that a tuple is immutable — its contents cannot be changed after it is created. There is no append(), no insert(), no remove(), no sort(), and writing to a position is refused. If a program tries events[0] = "Relay", Python stops it with an error instead of quietly doing it.
The commented-out line is the whole lesson. Remove the # and the program no longer runs — Python reports that a tuple does not support item assignment. That refusal is not a nuisance; it is the protection you asked for when you chose a tuple.
Because a tuple can never change, Python does not have to leave room for it to grow. This makes a tuple use slightly less memory than a list holding the same values, and makes it slightly quicker to create and read. For a handful of values you would never notice; over very large amounts of fixed data it is worth having.
20.6 Working with Tuples
A tuple refuses to be changed, but it does not refuse to be used. Everything that only reads a tuple works just as it does for a list.
20.6.1 Accessing Elements of a Tuple
Indexing and slicing work exactly as you learnt them in 20.3. The index of the first element is 0, negative numbers count back from the end, and a slice written as start:end stops just before the end index.
The one difference to notice is the shape of what comes back. A slice of a list is a list; a slice of a tuple is a tuple, and it prints with round brackets.
The first two lines print plain text, because a single element of this tuple is a piece of text. The third line prints a tuple, brackets and all, because a slice always hands back a group.
20.6.2 Operations on a Tuple
Tuples support every operation that leaves the original alone.
Two tuples can be joined with +, and a tuple can be repeated with *. Neither changes the tuples involved — a brand new tuple is produced, which is why immutability is not broken.
len(), min() and max() work on a tuple in the same way as on a list. So do the two searching methods, count() and index(), and the keyword in for checking whether a value is present at all.
What a tuple does not have is any method that alters it. There is no append(), no remove(), no sort() and no clear(), because every one of those would change the contents.
Unpacking a tuple
A tuple is often used to keep a few related facts about one thing together — a name, a class and a section, say. Unpacking pulls those values out into separate variables in one line, with the names on the left matching the elements in order.
The number of names on the left must match the number of elements exactly. Three elements need three names; giving two or four stops the program.
A tuple may also hold other tuples. Writing pairs = ((101, "Maths"), (102, "Science")) gives a tuple of two elements, and each of those elements is itself a tuple of a code and a subject name. pairs[0] would then be the whole first pair, and pairs[0][1] would be the text “Maths”.
20.6.3 Deleting a Tuple
Single elements of a tuple cannot be deleted — that is what immutable means. The whole tuple, however, can be thrown away when the program has finished with it, using the del statement.
After del codes runs, the name codes no longer exists. Using it again in the same program stops the program with a name error, because there is nothing left for Python to look up.
20.7 Lists and Tuples Compared
Lists and tuples do the same basic job: they hold several values under one name, in a settled order, reachable by index. Almost everything you can read out of one, you can read out of the other. The difference is what happens when something tries to change them.
If you are ever unsure which of the two a name is holding, ask Python.
Choosing between them
The question to ask is not “which is better?” but “is this data still going to change?”
Use a list when values are being collected, corrected or reordered while the program runs — marks being entered one by one, items being added to a bill, names waiting to be sorted into a merit list. Growing and rearranging are exactly what a list is for.
Use a tuple when the values are settled and any change would be a mistake — a fixed set of subject codes, the order of events on a programme card, a group of facts about one person that belong together. Here the refusal to change is a safety catch, not an obstacle.
The difference in memory and speed is real but small. For the sizes of data you will meet in school programs, it should not decide anything. Choose on whether the data must stay fixed, and the rest follows.
20.8 Converting a List into a Tuple and a Tuple into a List
Data does not always stay in the same state of readiness. Marks are collected one by one while the examination is being marked — that work needs a list. Once the marks are final and the result has been declared, nobody should be editing them any more, and a tuple is the safer place for them.
The reverse happens too. A tuple of subject codes is fixed, until the day a code is found to be wrong. The tuple itself cannot be corrected, but the values inside it can be moved somewhere that allows correction.
Python provides two functions for this. tuple() builds a tuple out of the values of a list, and list() builds a list out of the values of a tuple.
Locking a list once it is final
The last line is worth noticing. tuple() does not swallow the list or convert it in place — it reads the values and builds a separate tuple out of them. The list is still there afterwards, unchanged.
Correcting a value that is kept in a tuple
Suppose a tuple of subject codes holds 102 where it should hold 202, and a fourth code has to be added. The tuple cannot be edited, so the values are moved into a list, the changes are made there, and a fresh tuple is built from the result.
20.9 Summary
- A variable holds one value at a time, which is not enough when a program has to remember a whole set of related values. Both a list and a tuple hold many values under one name, in a settled order.
- A list is written with square brackets and commas. Each value in it is called an element, and elements may be of different types, may repeat, and may be added or removed at any time.
- A list is mutable — its contents can be changed after it has been created. This makes it the right choice for data that is still being collected or corrected.
- Every element has an index giving its position, counted from 0 for the first element. Negative index numbers count back from the end, so
-1is the last element. - Slicing takes a stretch of elements, written as
start:end. Python stops just before the end index, and hands back a new list without disturbing the original. - Elements are added with
append()at the end,insert()at a chosen position, andextend()when a whole second list is to be added. The+sign joins two lists into a new one and*repeats a list. - Elements are removed with
remove()by value,pop()by index, andclear()for the whole contents. An element is replaced by writing to its index. sort()arranges a list in ascending order, or in descending order withreverse=True.reverse()simply flips the current order. Both change the list itself.- Searching is done with
into check whether a value is present,index()to find where it first occurs, andcount()to find how many times it occurs. len(),min(),max()andsum()give the number of elements, the smallest, the largest and the total of a list of numbers.- A tuple is written with round brackets. A tuple of one element needs a comma after that element.
- A tuple is immutable — once created, no element can be replaced, added or removed. There is no
append(),remove()orsort()for a tuple. - Everything that only reads a tuple works as it does for a list: indexing, slicing,
in,index(),count(),len(),min()andmax(). Joining with+and repeating with*build a new tuple rather than changing the old one. - Unpacking assigns the elements of a tuple to separate variables in one line, and the number of variables must match the number of elements.
- Single elements of a tuple cannot be deleted. The whole tuple can be removed with
del. - Choose a list when the data will still change, and a tuple when it must stay fixed. A tuple also uses slightly less memory and is slightly faster, though for small amounts of data the difference does not matter.
tuple()builds a tuple from a list, andlist()builds a list from a tuple. To correct a value kept in a tuple, convert it to a list, make the change, and build a new tuple from the result.
20.10 Key Terms
Element – a single value stored inside a list or a tuple.
Immutable – unable to be changed after it has been created; a tuple is immutable.
Index – the position number of an element, counted from 0 for the first element, with negative numbers counting back from the end.
List – a Python data type that holds several values under one name, keeps them in a fixed order, and allows them to be changed, added or removed.
Method – an instruction that belongs to a particular value and is written after it with a dot, such as
append()inmarks.append(75).Mutable – able to be changed after it has been created; a list is mutable.
Slicing – taking a stretch of elements from a list or tuple by writing a start index and an end index, with Python stopping just before the end index.
Tuple – a Python data type that holds several values under one name in a fixed order, and does not allow them to be changed, added or removed once created.
20.11 Objective Questions
Which of the following creates a tuple in Python?
my_codes = [101, 102]my_codes = (101, 102)my_codes = {101, 102}my_codes = <101, 102>
Fill in the blank: the index of the first element of a list is __________, and the index of its last element can also be written as __________.
State whether the following statement is true or false: taking a slice of a tuple gives back a list.
What will be printed by the following code?
subjects = ["Maths", "Science", "English"]
subjects.insert(1, "Hindi")
print(subjects[2])- Hindi
- Science
- English
- Maths
- Match each instruction in Column A with what it does in Column B.
| Column A | Column B |
|---|---|
a. append() |
i. empties the list completely |
b. remove() |
ii. gives the position of the first matching element |
c. index() |
iii. adds one element at the end of the list |
d. clear() |
iv. deletes the first element having a given value |
- Write the output of the following code.
marks = [45, 62, 78, 51, 90]
print(marks[1:3])- Which one of the following can be done to a list but not to a tuple?
- Reading an element by its index
- Taking a slice
- Arranging the values in ascending order in place
- Counting how many times a value occurs
20.12 Concept Questions
Define a tuple, and give one situation from school life in which a tuple would be a better choice than a list.
Differentiate between
append()andextend(). Support your answer with one short example of each.A list holds eight elements. Explain why its last element is at index 7, and give a way of reaching that element without knowing how many elements the list holds.
A student writes
scores = scores.sort()and then printsscores. What gets printed, and why does the sorted list not appear? Give the correct way of writing it.Write a program that stores the six marks 45, 62, 78, 51, 90 and 66 in a list, and then prints the number of marks, the lowest mark, the highest mark and their total.
A tuple holds the subject codes
(201, 202, 203, 204). The third code has to be corrected to 303. Write a program that makes this correction, so that the final result is again a tuple, and prints it.
20.13 Case-Based Questions
- The librarian of your school keeps a record of the books issued during the day. By closing time the record looks like this.
issued = ["Wings of Fire", "The Jungle Book", "Panchatantra", "The Jungle Book"]- One more book, “Malgudi Days”, is issued just before closing. Write the instruction that adds it at the end of the record.
- The librarian wants to know how many times “The Jungle Book” was issued today. Which instruction gives this, and what value does it give for the record shown above?
- The librarian now wants the titles in alphabetical order. Name the method that does this, and state what happens to the order in which the books were actually issued.
- The order of events for sports day is printed on the programme card weeks in advance, and no part of the school’s program should be able to change it. It is stored like this.
events = ("100 m", "Long Jump", "Relay", "March Past")- Give one reason for storing these events in a tuple rather than in a list.
- Write the output of
print(events[-2]). - On the morning of sports day the relay is dropped and shot put takes its place. Explain, step by step, how “Relay” can be replaced by “Shot Put” so that the final result is again a tuple, and write the program that does it.