Learning Goals
3 minBy the end of this lesson you can:
- Place an item at any position with
.insert(i, value)— not just at the end. - Take items out of a list with
.remove()(by value) and.pop()(by index). - Reorder a list in place with
.sort()and.reverse(), and ask it questions with.index()and.count().
Warm-Up
5 minLevel 1 ended with a polished Number Guesser. Today we drop one level deeper into the data side of Python — starting with the friendly face we already know, the list.
Quick predict-the-output. Read it slowly:
orders = ["nasi lemak", "satay", "roti canai"] orders.append("milo") orders.insert(0, "teh tarik") print(orders)
Show the answer
['teh tarik', 'nasi lemak', 'satay', 'roti canai', 'milo']
append always lands at the back. insert(0, ...) slips a new item in at the very front and shoves everything else along.
Real orders change. Customers add things, cancel things, change their minds. Eight tiny list methods cover almost every change a real program will ever need to make.
New Concept · The Eight Most-Used List Methods
14 minAdding
.append(x) adds x to the end. We met it in L1. .insert(i, x) puts x at index i and pushes the rest along.
orders = ["nasi lemak", "satay"] orders.append("roti canai") # → [..., "roti canai"] orders.insert(0, "teh tarik") # → ["teh tarik", ...] print(orders)
['teh tarik', 'nasi lemak', 'satay', 'roti canai']
Removing
Two flavours:
.remove(value)— "take this item out". Removes the first matching value. If the value isn't in the list, you get aValueError..pop(i)— "take out the item at positioni". Returns it, so you can grab it on the way out. With no index,.pop()takes the last item.
orders = ["teh tarik", "nasi lemak", "satay", "roti canai"] orders.remove("satay") print(orders) # → ['teh tarik', 'nasi lemak', 'roti canai'] last = orders.pop() print(last) # → roti canai print(orders) # → ['teh tarik', 'nasi lemak']
.remove("satay") only removes the first "satay". If the list has two, the second one is still there. We'll handle that case with a while loop in the homework.
Reordering
.sort() rearranges the list in alphabetical or numerical order. .reverse() flips it end-to-end. Both change the list in place — they return None, so never write orders = orders.sort(), that wipes the list out.
prices = [8.00, 3.00, 5.50, 2.50] prices.sort() print(prices) # → [2.5, 3.0, 5.5, 8.0] prices.reverse() print(prices) # → [8.0, 5.5, 3.0, 2.5]
Need the original list left alone? Use the built-in sorted() — it hands back a brand-new sorted list and leaves the original untouched.
prices = [8.00, 3.00, 5.50] cheapest_first = sorted(prices) print(prices) # → [8.0, 3.0, 5.5] (unchanged) print(cheapest_first) # → [3.0, 5.5, 8.0]
Asking questions
.index(value) tells you where a value lives (its position). .count(value) tells you how many times it appears.
orders = ["satay", "nasi lemak", "satay", "milo", "satay"] print(orders.index("milo")) # → 3 print(orders.count("satay")) # → 3
The full cheat-sheet
add .append(x) .insert(i, x) remove .remove(value) .pop(i) .pop() order .sort() .reverse() sorted(lst) ask .index(value) .count(value) len(lst)
Eight methods plus two built-ins. Stick this on your wall — it covers nine out of ten list jobs you'll meet for the rest of Level 2.
Worked Example · A Saturday Lunch Rush
12 minThe story
You're running the till at Pak Cik Razif's warung. Six things happen in five minutes:
- First three customers order nasi lemak, satay and roti canai.
- The boss tells you teh tarik should always be on top of the list.
- Customer 2 changes her mind — cancel the satay.
- A take-away order pops off (last in, first packed).
- The kitchen wants the list in alphabetical order.
- How many nasi lemak orders are there in total?
Save as lunch_rush.py:
Code
# lunch_rush.py — five minutes at Pak Cik Razif's warung # Step 1 — the first three orders orders = ["nasi lemak", "satay", "roti canai"] orders.append("nasi lemak") # a fourth customer print("After 4 orders :", orders) # Step 2 — boss wants teh tarik on top orders.insert(0, "teh tarik") print("Boss's reorder :", orders) # Step 3 — cancel the satay orders.remove("satay") print("Satay cancelled:", orders) # Step 4 — pack the take-away (the last one) takeaway = orders.pop() print("Packed away :", takeaway) print("Still on pad :", orders) # Step 5 — alphabetical for the kitchen orders.sort() print("Sorted for KP :", orders) # Step 6 — how many nasi lemak? print("Nasi lemak qty :", orders.count("nasi lemak"))
Output
After 4 orders : ['nasi lemak', 'satay', 'roti canai', 'nasi lemak'] Boss's reorder : ['teh tarik', 'nasi lemak', 'satay', 'roti canai', 'nasi lemak'] Satay cancelled: ['teh tarik', 'nasi lemak', 'roti canai', 'nasi lemak'] Packed away : nasi lemak Still on pad : ['teh tarik', 'nasi lemak', 'roti canai'] Sorted for KP : ['nasi lemak', 'roti canai', 'teh tarik'] Nasi lemak qty : 1
Look at how the list changes line by line. Every method either grows, shrinks or reorders the same list — there's never a second copy floating around. That single "in place" idea is what makes lists so cheap to use.
The one trap
What happens if you try to remove an order that isn't there?
orders = ["teh tarik", "nasi lemak"] orders.remove("milo") # ← not in the list! # ValueError: list.remove(x): x not in list
Python crashes hard. In real apps we check first with in:
if "milo" in orders: orders.remove("milo") else: print("No milo to cancel.")
Try It Yourself
13 minThree exercises. Type the starter, then make the change. Try first, peek at the hint second.
Start from queue = ["Aisyah", "Wei Jie", "Priya"]. The teacher arrives and skips to the front. Insert "Cikgu" at index 0 and print the new queue.
Hint
queue = ["Aisyah", "Wei Jie", "Priya"] queue.insert(0, "Cikgu") print(queue)
Expected: ['Cikgu', 'Aisyah', 'Wei Jie', 'Priya'].
Given scores = [82, 47, 95, 60, 73], print them from highest to lowest. Use .sort() then .reverse().
Hint
scores = [82, 47, 95, 60, 73] scores.sort() scores.reverse() print(scores)
Or do it in one move with the built-in: scores = sorted(scores, reverse=True). We'll meet that reverse=True argument properly in L3.
Write a tiny program that starts with basket = ["apple", "orange", "apple", "pear"], asks the user which fruit to remove with input(), and removes it only if it's in the basket. Otherwise print That item isn't in the basket.
Hint
basket = ["apple", "orange", "apple", "pear"] item = input("Remove which fruit? ") if item in basket: basket.remove(item) print("Removed. Basket:", basket) else: print("That item isn't in the basket.")
The in check is the difference between a polished program and a crash. .remove() only kills the first matching item — run it twice on "apple" to see.
Mini-Challenge · The To-Do Manager
8 minBuild todo.py, a tiny menu-driven to-do list that uses six of the methods you met today.
Inside a while True: loop, print a four-option menu and act on each choice:
1— add a task (appendthe user's input).2— done with one (ask for the task name,removeit — but only if it's in the list).3— sort tasks alphabetically (sort) and print them.4— quit (breakout of the loop).
After every choice, print the current to-do list and how many items it has.
Stretch goal. Add option 5 — "most urgent", which uses pop(0) to take the first task off the list and prints it as the one to do next.
Show one possible solution
# todo.py — menu-driven to-do list tasks = [] while True: print() print("To-do list:", tasks, " (", len(tasks), "items )") print("1 add 2 done 3 sort 4 quit 5 most urgent") choice = input("Choose: ") if choice == "1": new = input("New task: ") tasks.append(new) elif choice == "2": which = input("Done with which? ") if which in tasks: tasks.remove(which) else: print("Not on the list.") elif choice == "3": tasks.sort() print("Sorted:", tasks) elif choice == "4": print("Bye!") break elif choice == "5": if len(tasks) == 0: print("Nothing urgent.") else: top = tasks.pop(0) print("Do this first:", top) else: print("Pick 1, 2, 3, 4 or 5.")
Your menu wording and exact prompts can vary. The non-negotiables are: a tasks list that starts empty, a while True loop, and the four core methods — append, remove (with an in guard), sort and break.
Recap
3 minLists grow with append and insert, shrink with remove and pop, reorder with sort and reverse, and answer questions with index, count and len. Most of those methods change the list in place — never reassign their return value, and never call .remove() on something that might not be there without an in check first.
Vocabulary Card
- .insert(i, x)
- Place
xat positioni, pushing the rest along. - .remove(value)
- Delete the first occurrence of
value. Crashes withValueErrorif not present. - .pop(i)
- Remove and return the item at index
i— defaults to the last item. - .sort() / .reverse()
- Reorder in place. Return
None— never reassign. - sorted(lst)
- Built-in that returns a new sorted list, leaving the original alone.
- .index(value) / .count(value)
- Position of the first match / number of matches.
Homework
4 minSave a new file clean_list.py. Start from this messy list of cinema-snack orders, with duplicates and weird spacing:
raw = ["popcorn", "nachos", "popcorn", "soda", "nachos", "popcorn", "candy"]
Your program must:
- Print the raw list and its length.
- Print how many popcorn and how many nachos orders there are using
.count(). - Remove all the popcorn entries — use a
whileloop with.remove()inside, so it keeps removing while"popcorn" in raw. - Sort the remaining list alphabetically and print it.
Stretch. Use sorted(raw) first to print a sorted copy without touching raw, then sort in place after.
Sample · clean_list.py
# clean_list.py — tidy a messy cinema-snack list raw = ["popcorn", "nachos", "popcorn", "soda", "nachos", "popcorn", "candy"] print("Raw :", raw) print("Length :", len(raw)) print("Popcorn:", raw.count("popcorn")) print("Nachos :", raw.count("nachos")) # Stretch — a sorted copy that leaves raw untouched print("Peek (sorted copy):", sorted(raw)) # Remove every popcorn while "popcorn" in raw: raw.remove("popcorn") raw.sort() print("Cleaned:", raw)
The non-negotiables are: the while "popcorn" in raw loop, at least one .count() call, and a sort at the end. The exact print labels can vary.