Store ordered data in lists, index and slice it, sort it, and use tuples for fixed groups of values.
Why it matters
Real data comes in collections: a week of temperatures, the students in a class, the rows of a file. A list holds many values in order under one name, so you can loop over them, pick out parts and sort them. A tuple is its fixed-size cousin, ideal for a group of values that belong together, such as a coordinate.
Creating and indexing lists
temps = [18, 21, 19, 25, 23, 17, 20]
names = ["Ada", "Grace", "Katherine"]
empty = []
mixed = ["sample-01", 23.4, True] # allowed, but usually one type per list is clearer
Each item has a position, its index, starting at 0. Negative indexes count from the end:
print(temps[0]) # 18 first item
print(temps[3]) # 25
print(temps[-1]) # 20 last item
print(temps[-2]) # 17
print(len(temps)) # 7
Asking for a position that does not exist, such as temps[7], raises IndexError: list index out of range. The last valid index is always len(temps) - 1.
Slicing
A slice list[start:stop] gives a new list from start up to, but not including, stop, the same rule as range:
temps = [18, 21, 19, 25, 23, 17, 20]
print(temps[0:3]) # [18, 21, 19] first three
print(temps[:3]) # [18, 21, 19] start defaults to 0
print(temps[4:]) # [23, 17, 20] stop defaults to the end
print(temps[-2:]) # [17, 20] last two
print(temps[::2]) # [18, 19, 23, 20] every second item (step 2)
print(temps[::-1]) # [20, 17, 23, 25, 19, 21, 18] reversed
Slicing never raises an IndexError; out-of-range bounds are simply trimmed. Strings slice the same way: "Python"[:3] is "Pyt".
Changing a list
Lists are mutable: you can change them after they are created.
queue = ["Ada", "Grace"]
queue.append("Katherine") # add to the end
queue.insert(0, "Alan") # insert at position 0
queue[1] = "Ada L." # replace an item
removed = queue.pop() # remove and return the last item
queue.remove("Grace") # remove the first matching value
print(queue) # ['Alan', 'Ada L.']
print("Alan" in queue) # True
Other useful tools: max(temps), min(temps), sum(temps), temps.count(19) and temps.index(25) (position of the first 25).
Sorting: sorted() versus .sort()
temps = [18, 21, 19, 25]
ordered = sorted(temps) # returns a NEW sorted list
print(ordered) # [18, 19, 21, 25]
print(temps) # [18, 21, 19, 25] unchanged
temps.sort(reverse=True) # sorts IN PLACE, returns None
print(temps) # [25, 21, 19, 18]
A classic bug is temps = temps.sort(), which replaces your list with None. Use sorted() when you want to keep the original.
Copying and aliasing
Assigning a list to another name does not copy it. Both names point to the same list:
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4] a changed too
c = a.copy() # or a[:] or list(a): a real copy
Tuples
A tuple looks like a list with parentheses, but it cannot be changed:
location = (51.5072, -0.1276) # latitude, longitude
print(location[0]) # 51.5072
location[0] = 0 # TypeError: 'tuple' object does not support item assignment
Use a tuple when the number and meaning of the items is fixed: a coordinate, an RGB colour, a (name, score) pair. Unpacking assigns each item to its own name:
lat, lon = location
print(f"{lat:.2f}, {lon:.2f}") # 51.51, -0.13
Functions that return several values (return low, high) are returning a tuple.
Lists of tuples: a small table
Lists and tuples combine into simple tables of records:
results = [("Ada", 91), ("Grace", 78), ("Katherine", 85)]
for name, score in results:
print(f"{name:10} {score}")
best = max(results, key=lambda pair: pair[1])
print("Top:", best[0]) # Top: Ada
key= tells max (and sorted) what to compare: here, the score in position 1. lambda pair: pair[1] is a tiny unnamed function. You will see this pattern often.
Common mistakes
- Off by one at the end. The last index is
len(x) - 1, or simplyx[-1]. x = x.sort()..sort()returnsNone. Usex.sort()alone orx = sorted(x).- Accidental aliasing.
b = ashares the list; usea.copy()for an independent copy. - Forgetting the comma in a one-item tuple.
(5)is just the number 5;(5,)is a tuple. - Confusing
appendandextend.a.append([4, 5])adds one item (a list);a.extend([4, 5])adds two.
Quick recap
- Lists are ordered and mutable; index from 0, or from the end with negatives.
- Slices
[start:stop:step]return new lists and excludestop. append,insert,pop,removechange a list in place.sorted()returns a new list;.sort()changes the list and returnsNone.- Tuples are fixed groups of values; unpack them with
a, b = pair.
Try it
In the Do tab you will slice a week of temperatures, sort a copy without changing the original, and unpack a coordinate tuple.