Programming Fundamentals

Lists, Tuples and Sets

↩ Back
01

Lists

Reference
Building a List

A list stores values in the order you wrote them, inside square brackets and separated by commas. Any type can go in, several types can share one list, and the same value may appear more than once.

scores = [7, 4, 9, 4] names = ["ana", "bo", "cy"] mixed = [3, "three", True] empty = [] print(len(scores)) # 4 print(scores[0]) # 7
What a list promises
OrderEvery value keeps the position it was given, and that position is how you reach it later.
RepeatsA value can appear many times. In scores the number 4 sits at two positions and counts twice.
GrowthThe list can gain and lose values while the program runs, without being rebuilt.
len(x) reports how many values a collection holds
Reference
Index and Slice

An index picks one value out of the list. A slice picks a section and hands back a new list, leaving the original where it was.

items = ["ant", "bee", "cat", "dog", "elk", "fox"] # 0 1 2 3 4 5 # -6 -5 -4 -3 -2 -1
Every form you need
FormMeaningExampleResult
items[i]the value at position iitems[0]'ant'
items[-i]counting back from the enditems[-1]'fox'
items[a:b]from a up to, and not including, bitems[1:4]['bee', 'cat', 'dog']
items[:b]from the start up to bitems[:2]['ant', 'bee']
items[a:]from a to the enditems[4:]['elk', 'fox']
items[a:b:c]same section, jumping by citems[0:6:2]['ant', 'cat', 'elk']
items[::-1]a reversed copyitems[::-1]['fox', 'elk', ...]
Where the two forms part ways

An index that does not exist raises IndexError and stops the program. A slice that runs past the end raises no error: it returns whatever positions it did find, and an empty list when it found none.

Reference
Changing a List

A list is mutable: the object keeps its name and its identity while its content changes. Assignment by index replaces one value, and the methods below add or drop values.

Each row below starts from the same list on the left, and the panel on the right shows what it looks like right after the call.

items[1] = "owl"replaces the value at position 1
Before
ant
bee
cat
After
ant
owl
cat
.append("owl")adds a value at the end
Before
ant
bee
cat
After
ant
bee
cat
owl
.insert(1, "owl")puts a value at position 1 and pushes the rest right
Before
ant
bee
cat
After
ant
owl
bee
cat
.remove("bee")drops the first matching value, raises ValueError when absent
Before
ant
bee
cat
After
ant
cat
last = .pop()drops the last value and returns it last = 'cat'
Before
ant
bee
cat
After
ant
bee
.sort()reorders the list in place, returns None
Before
cat
ant
bee
After
ant
bee
cat
.reverse()flips the order in place, returns None
Before
ant
bee
cat
After
cat
bee
ant
a + bbuilds a new list holding both, in order
Before
1
2
+
3
After
1
2
3
"cat" in itemstrue when the value is somewhere in the list, false otherwise
Before
ant
bee
cat
After
True

Reassign or not
CallWhat it returnsWrite it as
.append, .insert, .remove, .sort, .reverseNoneitems.sort()
.popthe value it removedvalue = items.pop()
a + b, v in itemsa new value, items stays as it wasresult = a + b
items = items.sort() sets items to None, since None is what sort returns.
02

Tuples

Reference
A List That Cannot Change

A tuple is written with parentheses and is fixed the moment it is created. Reading works as it does in a list, and every attempt to write raises an error.

point = (3, 5) colour = (255, 0, 90) one = (7,) # the comma makes it a tuple plain = (7) # an integer number in brackets print(point[0]) # 3 print(point[:1]) # (3,) print(len(colour)) # 3
Three details that catch people out
The commaThe comma builds the tuple and the parentheses only group it. A single value needs that trailing comma or Python reads brackets as ordinary grouping.
ReadingIndex, negative index, slicing, len and in behave as in a list. Slicing a tuple returns a tuple.
WritingThere is no append, no insert and no assignment by index. point[0] = 9 raises TypeError.
a tuple is fixed in size and in content, from creation to the end
Detail
Unpacking a Fixed Record

Because the size of a tuple is fixed, Python can hand its values to several names in one line. That move is called unpacking, and the number of names has to match the number of values.

point = (3, 5) x, y = point print(x + y) # 8 a, b = 1, 2 a, b = b, a # swap, no third name needed print(a, b) # 2 1

Reach for a tuple when the shape of the data never changes: a coordinate, a colour, a pair of values returned together. The fixed size is a promise to whoever reads the code later, and it also protects the values from being edited by accident.

Choose a tuple to say this will not change, and a list to say this will.
Interactive
Mutation Test

The two fragments differ in one character: square brackets on the left, parentheses on the right. Run both and read what Python says about the second one.

A list
A tuple
box = [1, 2, 3]box[0] = 99print(box)
box = (1, 2, 3)box[0] = 99print(box)
Output
press run to execute
Output
press run to execute

The error arrives at line 2, so the print on line 3 never runs. An immutable object refuses the assignment rather than making a quiet copy.

Comparison
List or Tuple
Questionlisttuple
Written with[ ]( )
Order keptYesYes
Repeats keptYesYes
Changes after creationYes, in placeNever
Index and sliceYesYes
Typical useA collection that grows, shrinks and gets sortedA record with a fixed shape, or values returned together
03

Sets

Reference
No Positions, No Repeats

A set holds each value once and holds no positions. Writing the same value twice changes nothing, and asking for element 0 raises TypeError because there is no element 0 to ask for.

tags = {"red", "blue", "red"} print(tags) # {'red', 'blue'} print(len(tags)) # 2 print("red" in tags) # True empty = set() # {} would build a dictionary nums = set([4, 4, 7]) # {4, 7}
What you trade and what you gain
You lose orderNo indexing, no slicing, no sorting in place. The values arrive in whatever order Python finds convenient.
You lose repeatsAdding a value that is already there leaves the set untouched, which makes a set the shortest way to drop duplicates.
You gain speedThe question v in tags is answered without walking through the values, so it stays fast on large collections.
Two traps

Empty braces build a dictionary rather than a set, so an empty set has to be written set(). And the order you see when printing a set is not the order you wrote and may change between runs, so never write code that depends on it.

Reference
Adding, Removing, Combining

A set changes in place just like a list, and a pair of sets can combine into a third one. Each row below starts from the same set on the left, and the panel on the right shows the result right after the call.

.add("green")puts a value in, or leaves the set as it was when already present
Before
red
blue
After
red
blue
green
.discard("red")drops a value when present, stays quiet when absent
Before
red
blue
After
blue
.remove("red")drops a value, raises KeyError when absent
Before
red
blue
After
blue
"blue" in tagstrue when the value is a member, false otherwise
Before
red
blue
After
True
A | Bunion, every value in either set, also written A.union(B)
Before
1
2
3
4
|
3
4
5
After
1
2
3
4
5
A & Bintersection, only the values present in both, also written A.intersection(B)
Before
1
2
3
4
&
3
4
5
After
3
4
A - Bdifference, in A and not in B, also written A.difference(B)
Before
1
2
3
4
3
4
5
After
1
2
A ^ Bsymmetric difference, in one set or the other, not in both, also written A.symmetric_difference(B)
Before
1
2
3
4
^
3
4
5
After
1
2
5
A <= Btrue when every value of A is also in B, also written A.issubset(B)
Before
3
4
<=
3
4
5
After
True

Reassign or not
CallWhat it returnsWrite it as
.add, .discard, .removeNonetags.add("green")
|, &, -, ^, <=a new set, or a boolean for <=result = A | B
04

Choosing and Converting

Comparison
The Three Compared
Questionlisttupleset
Written with[1, 2, 2](1, 2, 2){1, 2}
Position mattersYesYesNo
Changes after creationYesNoYes
Repeats keptYesYesNo
Index and sliceYesYesNo
Reach for it whenThe order is part of the meaning and the content movesThe record has a fixed shape that must stay fixedYou care about membership, not about position
order matters → list · fixed record → tuple · membership only → set
Reference
Moving Between Them

Each type has a function that builds it from any of the others. The conversion keeps whatever the target type promises and drops the rest.

names = ["bo", "ana", "bo", "cy"] unique = set(names) # {'bo', 'ana', 'cy'}, repeats gone back = list(unique) # a list again, in no promised order fixed = tuple(names) # ('bo', 'ana', 'bo', 'cy') tidy = sorted(set(names)) # ['ana', 'bo', 'cy'] print(len(names), len(unique)) # 4 3

Passing a list through a set is the shortest way to drop duplicates, and it costs you the original order. When the order matters, wrap the result in sorted, which returns a list arranged from small to large.

Every conversion is a new object. The collection you converted stays untouched.
Detail
Loops Meet Collections

The for loop from the previous guide walks all three types with the same header, one value per pass. Counting with range is only needed when the position itself is part of the work.

Walking the values
Walking the positions
names = ["bo", "ana", "cy"]for name in names: print(name)
names = ["bo", "ana", "cy"]for i in range(len(names)): print(i, names[i])
Output
press run to execute
Output
press run to execute
Adding as you go
scores = [7, 4, 9]total = 0for s in scores: total = total + sprint(total)
Output
press run to execute
05

Check Yourself

Question
What Does This Print?
The code
items = ["a", "b", "c", "d"] print(items[1:3])
Pick one.
Challenge
Predict Four Outputs

Trace each fragment before pressing Check. The answer button is there for when your trace and the verdict disagree.

type the values separated by spaces · brackets, braces, commas and quotes are ignored
1Counting back
letters = ["a", "b", "c", "d", "e"] print(letters[-2])
2Two methods in a row
nums = [3, 1, 2] nums.append(1) nums.sort() print(nums)
3Slicing a tuple
point = (3, 5, 8) print(point[1:])
4In one set or the other
A = {1, 2, 3, 4} B = {3, 4, 5} print(A ^ B)
06

Summary

Recap
What You Can Do Now
1
Build a list, read its length, and reach any value by its position from the front or from the back.
2
Read and write every form of a slice, and say why the stop index is left out of the result.
3
Change a list with append, insert, remove, pop, sort and reverse, and predict the list each one leaves behind.
4
Write a tuple, unpack it into separate names, and explain which operations it refuses and why.
5
Build a set, add and drop members, and compute union, intersection and both differences.
6
Pick the type a task calls for, convert between the three, and name what each conversion drops.