Goal
You’ll be able to create, access, and modify lists confidently, and understand Python’s negative indexing — a genuinely useful feature many beginners don’t discover until much later than they should.
Learn
A list holds an ordered collection of items, which can be changed after creation (lists are mutable, unlike strings):
fruits = ["apple", "banana", "cherry"]
fruits[0] # "apple" — indexing starts at 0
fruits.append("date") # adds to the end
fruits.remove("banana") # removes by value
len(fruits) # 3 (after the removal, before the append accounted) Python supports negative indexing — a genuinely useful shortcut for accessing items from the end of a list without needing to know its exact length:
fruits[-1] # last item fruits[-2] # second-to-last item
This works because Python interprets -1 as “one position from the end,” rather than requiring you to calculate len(fruits) - 1 manually every time.
Lists also support slicing — extracting a sub-portion:
numbers = [10, 20, 30, 40, 50] numbers[1:3] # [20, 30] — items from index 1 up to (not including) index 3 numbers[:2] # [10, 20] — from the start up to index 2 numbers[2:] # [30, 40, 50] — from index 2 to the end
The genuinely important detail with slicing: the end index is always exclusive — numbers[1:3] does NOT include the item at index 3, only indices 1 and 2.
Decision Task
You have scores = [85, 92, 78, 95, 88] and want the last two scores without knowing the list’s exact length in advance. Before reading on: how would you write this using negative indexing/slicing?
Show Answer
scores[-2:] — this slices from the second-to-last position to the end, correctly returning [95, 88] regardless of the list’s actual total length, since negative indices are always relative to the end, not a fixed absolute position that would need recalculating if the list’s size changed.
Common Mistake
Assuming a slice like numbers[1:3] includes the item at index 3. The end index in a slice is always exclusive — it goes up to but does not include that position. This is a genuinely common off-by-one mistake, especially for anyone coming from a language with different slicing conventions.
Practice Questions
1. Given colors = ["red", "green", "blue", "yellow"], what does colors[-1] return?
Show Answer
“yellow” — the last item, accessed via negative indexing.
2. Write code that adds “purple” to the end of the colors list.
Show Answer
colors.append("purple")
3. Given numbers = [1,2,3,4,5,6], what does numbers[2:5] return, and why doesn’t it include index 5?
Show Answer
[3, 4, 5] — slicing’s end index is always exclusive, so it stops right before index 5, including only indices 2, 3, and 4.
4. True or False: unlike strings, lists in Python are mutable — their contents can be changed in place after creation.
Show Answer
True — this is a genuine, important difference from strings covered in Part 1.3; list methods like append() and remove() do modify the original list directly.
5. Write an expression that gets the second-to-last item of a list called items, using negative indexing.
Show Answer
items[-2]
Try It Yourself
Without looking back, given data = [10, 20, 30, 40, 50], write an expression that returns everything except the first and last items, using slicing.
Show Answer
data[1:-1] — starting from index 1 (skipping the first item) up to (but not including) index -1 (the last item), correctly returning [20, 30, 40].
Quick Check
1. What index does list indexing start at in Python?
Show Answer
0
2. What does a negative index like -1 refer to?
Show Answer
The last item in the list; -2 the second-to-last, and so on, counting from the end.
3. In slicing, is the end index inclusive or exclusive?
Show Answer
Exclusive — it goes up to but does not include that position.
4. Are lists mutable or immutable in Python?
Show Answer
Mutable — their contents can be changed after creation, unlike strings.
5. What method adds an item to the end of a list?
Show Answer
.append()