Lists and Tuples
Model ordered data with mutable lists and fixed-shape immutable tuples.
Lists and tuples are ordered sequences. Both support iteration, indexing, slicing, membership,
and len. Their main difference is mutability.
Lists: editable ordered collections
tasks = ["read", "practice", "review"]
print(tasks[0]) # read
print(tasks[-1]) # review
print(tasks[1:]) # ['practice', 'review']
print("read" in tasks) # TrueLists may contain mixed types, but collections of one conceptual kind are usually easier to process.
Common methods mutate the list:
tasks.append("build")
tasks.extend(["test", "share"])
tasks.insert(1, "plan")
tasks.remove("review") # removes first equal value
last = tasks.pop() # removes and returns final valueremove raises ValueError if the value is absent; pop raises IndexError when the selected
position does not exist.
Other useful methods:
numbers = [3, 1, 3, 2]
print(numbers.count(3)) # 2
print(numbers.index(2)) # 3
numbers.reverse()
numbers.clear()Sorting lists
list.sort() mutates a list and returns None. sorted() accepts any iterable and returns a
new list:
scores = [72, 95, 81]
ascending = sorted(scores)
print(scores) # [72, 95, 81]
print(ascending) # [72, 81, 95]
scores.sort(reverse=True)
print(scores) # [95, 81, 72]Use a key function to define what is compared:
names = ["Grace", "ada", "Guido"]
print(sorted(names, key=str.casefold))Sorting is stable: records with equal keys preserve their original relative order.
Copying and nested lists
Assignment shares one list:
original = ["a", "b"]
alias = original
alias.append("c")
print(original) # ['a', 'b', 'c']A shallow copy creates a new outer list:
copy = original.copy()
copy.append("d")Nested objects remain shared in a shallow copy. Use copy.deepcopy only when truly independent
nested mutable data is required; often a clearer data model avoids the need.
Do not create a grid with repeated inner-list references:
# wrong: rows = [[0] * 3] * 3
rows = [[0] * 3 for _ in range(3)]
rows[0][0] = 1
print(rows) # [[1, 0, 0], [0, 0, 0], [0, 0, 0]]Tuples: fixed-shape records
Tuples cannot have elements added, removed, or replaced:
point = (4, 7)
x, y = point
print(x, y) # 4 7Parentheses do not create a one-item tuple; the comma does:
singleton = (42,)
not_a_tuple = (42)Tuples can contain mutable objects, and those nested objects can still change:
record = ("Ada", ["math", "poetry"])
record[1].append("computing")The tuple's references are fixed; the referenced list is not immutable.
Choosing list versus tuple
Choose a list when:
- items form a changing collection;
- you will append, remove, reorder, or replace items;
- all elements play the same conceptual role, such as a list of scores.
Choose a tuple when:
- positions form a fixed record, such as
(latitude, longitude); - the structure should communicate “do not resize or reassign”;
- hashable contents are needed as a dictionary key or set member;
- a function naturally returns several related values.
Neither is automatically “better” or meaningfully faster for ordinary design decisions. Choose the type that communicates the data's intended behavior.
Sequence unpacking
first, second, third = ["red", "green", "blue"]
head, *middle, tail = [10, 20, 30, 40, 50]
print(head) # 10
print(middle) # [20, 30, 40]
print(tail) # 50Exactly one starred target may collect remaining items. Unpacking works with any iterable, not only lists and tuples.
Common mistakes
- Assigning the result of a mutating method:
items = items.append(value)makesitemsNone. - Modifying a list while iterating over it, which can skip elements.
- Expecting slicing or
.copy()to deeply copy nested values. - Omitting the comma in a one-item tuple.
- Using a tuple for data that must be updated frequently.
- Relying on numerical positions for a large record; a class or named record is clearer.
Decision guidance
- Need order, duplicates, and mutation? Use a list.
- Need order and a small fixed structure? Use a tuple.
- Need fast lookup by meaningful keys? Use a dictionary.
- Need unique membership with no positional meaning? Use a set.
- Use
sorted(data)when the original order matters; usedata.sort()when deliberate mutation is appropriate.
Practice
- Add and remove tasks from a list without assigning method return values.
- Sort names case-insensitively while preserving the original list.
- Represent an RGB color as a tuple and unpack its channels.
- Build a 4-by-4 independent grid and change only its bottom-right cell.
LEARNING RECORD
Finish this lesson
Mark it complete when you can explain the main decision without looking.
KNOWLEDGE CHECK