Learn
03.2 | LISTS, INDEXING AND SLICING
01 | ONE NAME FOR RELATED VALUES
Suppose a quiz records several scores. Separate names score1, score2 and score3 make repeating work awkward. A list groups related values in one ordered collection.
Write list literals with square brackets and commas between items. scores = [8, 5, 12] creates three items. Python lists can contain different types, but a consistent meaning usually makes processing clearer.
Unlike the string, a list is mutable: its items and size can be changed. Unlike a fixed-size typed pseudocode array, a Python list can grow or shrink.
scores = [8, 5, 12] print(scores) print(len(scores))
EXPECTED OUTPUT
[8, 5, 12] 3
02 | INDEXING STILL BEGINS AT ZERO
scores[0] retrieves eight, scores[1] retrieves five and scores[-1] retrieves twelve. The index identifies the position; the item at that position is the stored value.
A variable can supply the index. If position is one, scores[position + 1] reads index two. scores[position] + 1 reads index one and adds one to its value. Those expressions answer different questions.
An invalid single index raises IndexError. An empty list has no valid item index, even though its length can safely be read.
scores = [8, 5, 12] position = 1 print(scores[position + 1]) print(scores[position] + 1)
EXPECTED OUTPUT
12 6
03 | UPDATE AN ITEM IN PLACE
Assigning scores[1] = 10 changes the item at index one. Other positions keep their values. This works because the list is mutable.
Distinguish an element assignment from replacing the whole variable. scores = [10] would bind scores to a different one-item list. scores[1] = 10 modifies the existing list.
Use a trace to record the entire current list after important edits. Position and value should not be swapped accidentally.
scores = [8, 5, 12] scores[1] = 10 print(scores)
EXPECTED OUTPUT
[8, 10, 12]
04 | APPEND, EXTEND AND INSERT
append(value) adds one item at the end. extend(values) adds each item from an iterable. insert(index, value) puts an item before the selected position.
Appending [1, 2] adds one nested list item. Extending with [1, 2] adds two numeric items. The difference affects both length and the shape of the data.
These mutating methods return None, not the updated list. Write scores.append(7), not scores = scores.append(7), which would replace the name with None.
scores = [8, 5] scores.append(12) scores.extend([7, 9]) scores.insert(1, 10) print(scores)
EXPECTED OUTPUT
[8, 10, 5, 12, 7, 9]
05 | REMOVE A VALUE OR POP A POSITION
remove(value) deletes the first equal item. It raises ValueError when the value is absent. pop(index) removes and returns the item at that index; with no argument it uses the last item.
Check membership with in when absence is an expected case. pop on an empty list or invalid position raises IndexError. Removing an item shifts later positions, so indices are not permanent identities.
scores = [8, 5, 8] scores.remove(8) last = scores.pop() print(scores) print(last)
EXPECTED OUTPUT
[5] 8
06 | SLICING MAKES A NEW OUTER LIST
scores[1:3] takes indices one and two, excluding three. A slice returns a new list containing those selected items. It does not remove them from scores.
For a flat list of immutable numbers, changing the copy’s first item does not replace the original list’s first item. With nested mutable objects, however, a shallow copy still refers to the same inner objects. That distinction is developed in the nested-collections lesson.
scores = [8, 5, 12] copy_scores = scores[:] copy_scores[0] = 99 print(scores) print(copy_scores)
EXPECTED OUTPUT
[8, 5, 12] [99, 5, 12]
07 | A SECOND NAME IS NOT A COPY
backup = scores makes both names refer to the same list. A change through either name is visible through the other. This is aliasing, not a separate snapshot.
Use scores.copy() or scores[:] when you need a new outer list. Do not generalise the Section 1 numeric-copy example into “every assignment makes an independent collection”. Assignment binds names; the object’s mutability changes what later edits can do.
scores = [8, 5, 12] backup = scores backup[0] = 99 print(scores)
EXPECTED OUTPUT
[99, 5, 12]
08 | ITERATE OVER VALUES DIRECTLY
for score in scores gives each item value in list order. You do not need an index just to process every value. Use an accumulator to calculate the sum or the built-in sum when the task is straightforward.
Guard a mean when the list might be empty. len(scores) is the item count, not the largest valid index. Avoid changing the list’s size while iterating over it unless you deliberately design for that behaviour.
scores = [8, 5, 12]
total = 0
for score in scores:
total += score
if scores:
print("Mean:", total / len(scores))
else:
print("No scores")09 | SORT IN PLACE OR REQUEST A SORTED COPY
scores.sort() rearranges the existing list and returns None. sorted(scores) returns a new sorted list, leaving the source order unchanged.
Ascending is the default. reverse=True requests descending order. The values must have a meaningful supported ordering: mixing unrelated strings and numbers does not automatically give a useful numeric order.
Sorting changes positions, so a list index is not a stable record identifier. Keep related data together when you need a name to remain paired with its score.
scores = [8, 5, 12] ranked = sorted(scores, reverse=True) print(ranked) print(scores)
EXPECTED OUTPUT
[12, 8, 5] [8, 5, 12]
10 | EXPERIMENT WITH A SMALL LIST
The demo starts with [8, 5, 12]. Read an index, replace an item, append a number or take a slice. Each edit shows the current state. Restart when you want to compare a different sequence from the original values.
11 | BUILD A READING REGISTER
Collect three whole-number readings into an initially empty list using a for loop and append. Then display the list, maximum, minimum and a mean.
max and min return the largest and smallest item and require a non-empty list for this simple use. Your fixed three-reading version guarantees that count when successful inputs are supplied. A future variable-length version should check emptiness.
Challenge: make a sorted copy for display and prove that the original arrival order remains unchanged. Explain the difference between an alias and that copy.
PUT YOUR SKILLS TO WORK
Use the Section 3 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.
Section 3 challenges Python course navigation