Lesson 08 – Python Lists Advanced: Looping, Comprehensions, Sorting, Copying, Joining & Methods
Lesson 08 – Python Lists Advanced: Looping, Comprehensions, Sorting, Copying, Joining & Methods
Lesson Introduction
Welcome to Lesson 08 — one of the most practically powerful lessons in your Python journey.
In earlier lessons you learned what a list is, how to create one, and how to read or change items inside it. Now you are going to learn how to do things with entire lists — how to move through every item automatically, how to build brand-new lists from scratch in one line, how to put lists in order, how to make safe copies, how to combine two lists together, and how to use Python’s built-in list toolbox.
By the end of this lesson you will be able to:
- Loop through every item in a list automatically using
forandwhile - Build new lists in one elegant line using list comprehensions
- Sort a list alphabetically, numerically, in reverse, or using a custom rule
- Copy a list safely so changes to one copy do not accidentally affect the other
- Join two or more lists together
- Use all of Python’s built-in list methods (
append,remove,pop,count,index, and more) - Build a realistic mini-project combining all of these skills
There is no assumed prior knowledge beyond knowing that a list is a collection of items written in square brackets. Every new term will be explained from scratch.
Prerequisite Concepts (Read This First)
Before diving in, let’s make sure you are comfortable with three small ideas that appear constantly in this lesson.
What Is a List? (Quick Reminder)
A list in Python is a container that holds multiple values in a specific order. Each value has a numbered position called an index, starting from 0.
fruits = ["apple", "banana", "cherry"]
# index 0 index 1 index 2
You can access one item by writing fruits[0] (gives "apple").
What Is a Loop?
A loop is a Python instruction that says: “repeat these lines of code multiple times automatically.”
Without loops, to print three fruits you would write:
print(fruits[0])
print(fruits[1])
print(fruits[2])
That is only 3 lines. But what if you had 1 000 fruits? Loops solve this problem.
What Is a Function / Method?
A function is a saved block of code with a name. You run it by writing its name followed by ().
A method is a function that belongs to a specific thing (like a list). You call it with a dot:
fruits.sort() # .sort() is a method that belongs to the list called fruits
You will learn many list methods throughout this lesson.
Part 1 — Looping Through a List
1.1 What Is Looping and Why Do We Need It?
The problem without loops:
Imagine you have a shopping list with 50 items and you want to print all of them. Writing 50 individual print() lines is slow, messy, and impractical. If you add item 51 later, you have to add another line manually.
The solution — a loop:
A loop says: “Go through every item in this list, one at a time, and do something with each one.” The loop adjusts automatically no matter how many items the list contains.
Real-world analogy: Think of a cashier at a supermarket. They don’t have separate instructions for each product on the conveyor belt. They have one rule: “scan the item, enter the price, move to the next one.” That one rule loops over every product automatically. Python loops work the same way.
1.2 The for Loop — Looping Directly Through Items
The most common way to loop through a list in Python is the for loop. It reads almost like plain English.
Syntax:
for variable_name in list_name:
# do something with variable_name
variable_nameis a temporary label you make up — it holds one item from the list at a time.in list_nametells Python which list to go through.- The indented block below runs once for each item.
Example 1 — Print every fruit:
fruits = ["apple", "banana", "cherry"]
for x in fruits:
print(x)
Expected Output:
apple
banana
cherry
What happened, step by step?
| Loop Turn | What x holds |
What gets printed |
|---|---|---|
| 1st | "apple" |
apple |
| 2nd | "banana" |
banana |
| 3rd | "cherry" |
cherry |
After the 3rd turn, the list has no more items, so the loop ends automatically.
💡 Tip: The variable name
xis just a convention. You could writefor fruit in fruits:orfor item in fruits:— any name works. Pick something readable.
Example 2 — Do something with each item:
temperatures = [22, 18, 30, 25, 17]
for temp in temperatures:
print(temp + 273) # Convert Celsius to Kelvin
Expected Output:
295
291
303
298
290
🤔 Think about it: What would happen if you added a 6th temperature to the list? Would you need to change the loop?
1.3 The for Loop with range() and Index Numbers
Sometimes you need to know which position (index) you are at, not just the value. This is useful when you want to change items inside the list or when you need to show numbered output.
range(len(list_name)) explained:
len(fruits)counts how many items are in the list. For["apple","banana","cherry"]it returns3.range(3)produces the numbers0, 1, 2— exactly the valid index positions.- So the loop visits index 0, then 1, then 2.
Example 3 — Print with index numbers:
fruits = ["apple", "banana", "cherry"]
for i in range(len(fruits)):
print(i, fruits[i])
Expected Output:
0 apple
1 banana
2 cherry
Example 4 — Number a shopping list starting from 1:
shopping = ["milk", "eggs", "bread", "butter"]
for i in range(len(shopping)):
print(str(i + 1) + ". " + shopping[i])
Expected Output:
1. milk
2. eggs
3. bread
4. butter
💡 Note: We write
i + 1because indexes start at 0, but humans count from 1.
1.4 The while Loop — Looping with a Condition
A while loop keeps repeating as long as a condition is True. It is another way to loop through a list when you want fine control over how the loop moves.
Syntax:
i = 0
while i < len(list_name):
# do something with list_name[i]
i += 1 # MUST increase i each time, or the loop runs forever!
Example 5 — Print every fruit with a while loop:
fruits = ["apple", "banana", "cherry"]
i = 0
while i < len(fruits):
print(fruits[i])
i += 1
Expected Output:
apple
banana
cherry
Step-by-step trace:
| Step | i value |
Condition i < 3 |
What prints | After i += 1 |
|---|---|---|---|---|
| 1 | 0 | True | apple | i = 1 |
| 2 | 1 | True | banana | i = 2 |
| 3 | 2 | True | cherry | i = 3 |
| 4 | 3 | False → STOP | — | — |
⚠️ Common Beginner Mistake — Forgetting
i += 1:# WRONG — this runs forever (infinite loop)! i = 0 while i < len(fruits): print(fruits[i]) # forgot to write i += 1Always make sure your
whileloop has a line that eventually makes the conditionFalse.
1.5 The break Statement — Exiting a Loop Early
break immediately exits the loop, even if there are more items left.
Example 6 — Stop when you find “banana”:
fruits = ["apple", "banana", "cherry"]
for x in fruits:
if x == "banana":
break
print(x)
Expected Output:
apple
The loop printed apple, then hit banana and stopped. cherry was never reached.
1.6 The continue Statement — Skipping One Item
continue skips the rest of the current loop turn and jumps to the next item.
Example 7 — Skip “banana”, print everything else:
fruits = ["apple", "banana", "cherry"]
for x in fruits:
if x == "banana":
continue
print(x)
Expected Output:
apple
cherry
🤔 Think about it: What is the difference between
breakandcontinue?breakends the loop entirely.continueonly skips the current item and keeps going.
1.7 for Loop with else
Python has an unusual but useful feature: you can add an else block to a for loop. The else block runs after the loop finishes normally (i.e., it did NOT exit via break).
Example 8:
fruits = ["apple", "banana", "cherry"]
for x in fruits:
print(x)
else:
print("Loop finished!")
Expected Output:
apple
banana
cherry
Loop finished!
Part 1 — Practice Exercise
Scenario: You are a teacher and you have a list of student test scores. Write a program that:
- Prints every score
- Prints how many scores are above 50
scores = [45, 72, 88, 33, 91, 50, 67]
count_pass = 0
for score in scores:
print(score)
if score > 50:
count_pass += 1
print("Students who passed:", count_pass)
Expected Output:
45
72
88
33
91
50
67
Students who passed: 4
🔍 Self-check: Why is 50 not counted as a pass? Because the condition is
> 50(strictly greater than), not>= 50.
Part 2 — List Comprehension
2.1 What Is a List Comprehension?
A list comprehension is a special Python syntax that creates a brand-new list in a single line of code.
Without comprehension (the “old way”):
fruits = ["apple", "banana", "cherry"]
newlist = []
for x in fruits:
newlist.append(x)
print(newlist)
Expected Output:
['apple', 'banana', 'cherry']
With comprehension (the “new way”):
fruits = ["apple", "banana", "cherry"]
newlist = [x for x in fruits]
print(newlist)
Expected Output:
['apple', 'banana', 'cherry']
Both produce identical results. The comprehension is shorter, faster, and once you understand it, easier to read.
2.2 The Anatomy of a List Comprehension
newlist = [expression for item in iterable if condition]
↑ ↑ ↑
What to put Where to get items Optional filter
in the list (a list, range, etc.)
- expression — What each item in the new list looks like (could be the item itself, a modified version, etc.)
- for item in iterable — Loop through every item from a list, range, or other collection
- if condition — (Optional) Only include items that pass this test
Think of it like a sentence: “Give me [expression] for each [item] in [iterable], but only if [condition].”
2.3 Comprehension Without a Condition (Simple Filter)
Example 9 — Copy a list:
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
newlist = [x for x in fruits]
print(newlist)
Expected Output:
['apple', 'banana', 'cherry', 'kiwi', 'mango']
2.4 Comprehension With a Condition (if Filter)
Example 10 — Only fruits whose name contains the letter “a”:
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
newlist = [x for x in fruits if "a" in x]
print(newlist)
Expected Output:
['apple', 'banana', 'mango']
Example 11 — Only numbers less than 5 from a range:
newlist = [x for x in range(10) if x < 5]
print(newlist)
Expected Output:
[0, 1, 2, 3, 4]
🤔 Think about it:
range(10)produces 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The conditionx < 5keeps only 0 through 4.
Example 12 — Exclude one item:
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]
newlist = [x for x in fruits if x != "apple"]
print(newlist)
Expected Output:
['banana', 'cherry', 'kiwi', 'mango']
2.5 Transforming Items (Modifying the Expression)
The expression part does not have to be just x. You can apply any transformation.
Example 13 — Convert all fruits to UPPERCASE:
fruits = ["apple", "banana", "cherry"]
newlist = [x.upper() for x in fruits]
print(newlist)
Expected Output:
['APPLE', 'BANANA', 'CHERRY']
Example 14 — Double every number in a list:
numbers = [1, 2, 3, 4, 5]
doubled = [x * 2 for x in numbers]
print(doubled)
Expected Output:
[2, 4, 6, 8, 10]
Real-world use case: A data analyst might use this to convert a column of temperatures from Celsius to Fahrenheit in one line:
celsius = [0, 10, 20, 30, 40]
fahrenheit = [(c * 9/5) + 32 for c in celsius]
print(fahrenheit)
Expected Output:
[32.0, 50.0, 68.0, 86.0, 104.0]
2.6 Conditional Expression Inside the Expression (if...else in the Expression)
You can also use an if/else directly inside the expression part (not the filter part) to choose between two values for each item.
Syntax:
newlist = [value_if_true if condition else value_if_false for item in iterable]
Example 15 — Replace “banana” with “orange”, keep everything else:
fruits = ["apple", "banana", "cherry"]
newlist = [x if x != "banana" else "orange" for x in fruits]
print(newlist)
Expected Output:
['apple', 'orange', 'cherry']
Explained: For each x in the list:
- If
xis NOT “banana” → keepxas-is - If
xIS “banana” → replace it with"orange"
Example 16 — Label numbers as “even” or “odd”:
numbers = [1, 2, 3, 4, 5, 6]
labels = ["even" if n % 2 == 0 else "odd" for n in numbers]
print(labels)
Expected Output:
['odd', 'even', 'odd', 'even', 'odd', 'even']
2.7 Using range() as the Iterable
You can use range() instead of an existing list to generate values on the fly.
Example 17 — Squares of numbers 1 through 5:
squares = [x ** 2 for x in range(1, 6)]
print(squares)
Expected Output:
[1, 4, 9, 16, 25]
2.8 Common Beginner Mistake — Confusing the Two if Positions
There are two places an if can go in a comprehension, and they do different things:
# FILTER if — goes AFTER the for clause, NO else allowed here
[x for x in fruits if x != "banana"] # Removes banana from results
# EXPRESSION if — goes BEFORE the for clause, MUST have else
[x if x != "banana" else "orange" for x in fruits] # Replaces banana with orange
⚠️ Wrong — trying to use else with a filter if:
# WRONG — SyntaxError [x for x in fruits if x != "banana" else "orange"]Move the
if/elseto the expression part (beforefor) when you need an else.
Part 2 — Practice Exercise
Scenario: You have a list of product prices. Create a new list that:
- Includes only prices greater than 10
- Applies a 10% discount to each qualifying price
prices = [5.99, 15.00, 8.50, 22.00, 3.75, 12.99]
discounted = [round(p * 0.9, 2) for p in prices if p > 10]
print(discounted)
Expected Output:
[13.5, 19.8, 11.69]
🔍 Self-check: Why are 5.99, 8.50, and 3.75 missing from the result?
Part 3 — Sorting a List
3.1 What Does Sorting Mean and Why Does It Matter?
Sorting means arranging the items in a list in a specific order — most commonly alphabetical (A to Z) or numerical (smallest to largest).
Why sort?
- A doctor needs patient records sorted by last name.
- A store needs products sorted by price (cheapest first).
- A teacher needs exam scores sorted highest to lowest.
- A search engine needs results sorted by relevance.
Python gives you two main tools for sorting:
.sort()— modifies the original list (in-place sort)sorted()— creates a new sorted list, leaving the original unchanged
3.2 The .sort() Method — Sort the Original List
.sort() rearranges the items inside the list permanently.
Example 18 — Sort strings alphabetically:
thislist = ["orange", "mango", "kiwi", "pineapple", "banana"]
thislist.sort()
print(thislist)
Expected Output:
['banana', 'kiwi', 'mango', 'orange', 'pineapple']
Example 19 — Sort numbers from smallest to largest:
thislist = [100, 50, 65, 82, 23]
thislist.sort()
print(thislist)
Expected Output:
[23, 50, 65, 82, 100]
💡 Remember:
.sort()changes the list itself. After calling it, the original order is gone.
3.3 Sort in Descending Order with reverse=True
Add reverse=True to sort from largest to smallest (numbers) or Z to A (strings).
Example 20 — Sort strings Z to A:
thislist = ["orange", "mango", "kiwi", "pineapple", "banana"]
thislist.sort(reverse=True)
print(thislist)
Expected Output:
['pineapple', 'orange', 'mango', 'kiwi', 'banana']
Example 21 — Sort numbers largest to smallest:
thislist = [100, 50, 65, 82, 23]
thislist.sort(reverse=True)
print(thislist)
Expected Output:
[100, 82, 65, 50, 23]
3.4 Case-Insensitive Sorting with key=str.lower
By default, Python sorts uppercase letters before lowercase letters (because uppercase letters have lower ASCII values). This can cause surprising results.
Example 22 — Default sort (case-sensitive, uppercase first):
thislist = ["banana", "Orange", "Kiwi", "cherry"]
thislist.sort()
print(thislist)
Expected Output:
['Kiwi', 'Orange', 'banana', 'cherry']
Kiwi and Orange appear first because Python sees capital letters as “smaller.”
Example 23 — Case-insensitive sort:
thislist = ["banana", "Orange", "Kiwi", "cherry"]
thislist.sort(key=str.lower)
print(thislist)
Expected Output:
['banana', 'cherry', 'Kiwi', 'Orange']
How key=str.lower works: Before comparing any two items, Python temporarily converts them to lowercase just for the comparison. The original capitalisation is kept in the final list — only the sorting logic uses lowercase.
3.5 Custom Sort Functions with key=
You can pass any function to key= to control how sorting decisions are made. The function receives each item and returns a value; Python sorts by those returned values.
Example 24 — Sort strings by their length (shortest first):
def my_func(e):
return len(e)
thislist = ["banana", "kiwi", "pineapple", "apple"]
thislist.sort(key=my_func)
print(thislist)
Expected Output:
['kiwi', 'apple', 'banana', 'pineapple']
len("kiwi") = 4, len("apple") = 5, len("banana") = 6, len("pineapple") = 9 — so sorted by those lengths.
Example 25 — Sort a list of numbers by their distance from 50:
def distance_from_50(n):
return abs(n - 50)
numbers = [100, 50, 65, 23, 48]
numbers.sort(key=distance_from_50)
print(numbers)
Expected Output:
[50, 48, 65, 23, 100]
💡
abs()returns the absolute value — the distance from zero, always positive. Soabs(23 - 50)=abs(-27)=27.
3.6 The .reverse() Method — Flip the List Order
.reverse() simply flips the list backwards. It does NOT sort — it just reverses whatever order the items are currently in.
Example 26:
fruits = ["banana", "Orange", "Kiwi", "cherry"]
fruits.reverse()
print(fruits)
Expected Output:
['cherry', 'Kiwi', 'Orange', 'banana']
3.7 The sorted() Built-in Function — Sort Without Changing the Original
sorted() returns a new sorted list and leaves the original list unchanged.
Example 27:
original = [100, 50, 65, 82, 23]
new_sorted = sorted(original)
print("Original:", original)
print("Sorted: ", new_sorted)
Expected Output:
Original: [100, 50, 65, 82, 23]
Sorted: [23, 50, 65, 82, 100]
🤔 When to use
.sort()vssorted()?
- Use
.sort()when you want to permanently sort the original list.- Use
sorted()when you want to keep the original list intact and work with a sorted copy.
Part 3 — Practice Exercise
Scenario: You run a small bookshop. You have a list of book prices. Display them sorted from cheapest to most expensive, and separately from most expensive to cheapest.
prices = [12.99, 7.50, 24.00, 3.99, 18.75, 9.00]
prices.sort()
print("Cheapest to most expensive:", prices)
prices.sort(reverse=True)
print("Most expensive to cheapest:", prices)
Expected Output:
Cheapest to most expensive: [3.99, 7.5, 9.0, 12.99, 18.75, 24.0]
Most expensive to cheapest: [24.0, 18.75, 12.99, 9.0, 7.5, 3.99]
Part 4 — Copying a List
4.1 The Problem with Direct Assignment
This is one of the most important and surprising concepts for beginners. Many new Python learners make a critical mistake here.
Example 28 — The Dangerous Mistake:
list1 = ["apple", "banana", "cherry"]
list2 = list1 # THIS IS NOT A COPY — it's a second name for the SAME list
list2.append("date")
print(list1) # Expected ['apple','banana','cherry'] — SURPRISE!
print(list2)
Expected Output:
['apple', 'banana', 'cherry', 'date']
['apple', 'banana', 'cherry', 'date']
Why? When you write list2 = list1, Python does NOT create a new list. Instead, list2 becomes another label pointing to the exact same list in memory. Any change made via list2 is also visible via list1, because they are the same object.
Analogy: Imagine a house and two keys. If you give your friend a copy of your house key (same lock), they can enter your house. If they move the furniture, you’ll find it moved too. list2 = list1 is like giving your friend a key — not a separate identical house.
To get a separate identical house, you need to actually build a copy.
4.2 Copying with the .copy() Method
Example 29 — Safe copy with .copy():
list1 = ["apple", "banana", "cherry"]
list2 = list1.copy() # Creates a REAL independent copy
list2.append("date")
print(list1) # Original — unchanged
print(list2) # Copy — has the new item
Expected Output:
['apple', 'banana', 'cherry']
['apple', 'banana', 'cherry', 'date']
Now list1 and list2 are completely independent. Changes to one do not affect the other.
4.3 Copying with the list() Constructor
Another clean and readable way to copy a list is to pass it to the built-in list() function:
Example 30:
list1 = ["apple", "banana", "cherry"]
list2 = list(list1) # Creates a new list with the same contents
list2[0] = "mango"
print(list1) # Unchanged
print(list2) # Modified copy
Expected Output:
['apple', 'banana', 'cherry']
['mango', 'banana', 'cherry']
4.4 Copying with Slice Notation [:]
A third common approach is the full slice. Slicing always returns a new list.
Example 31:
list1 = ["apple", "banana", "cherry"]
list2 = list1[:] # Full slice = entire list as a new copy
list2.remove("banana")
print(list1)
print(list2)
Expected Output:
['apple', 'banana', 'cherry']
['apple', 'cherry']
4.5 Summary — Three Ways to Copy a List
| Method | Code | Creates independent copy? |
|---|---|---|
.copy() |
list2 = list1.copy() |
✅ Yes |
list() |
list2 = list(list1) |
✅ Yes |
Slice [:] |
list2 = list1[:] |
✅ Yes |
| Direct assignment | list2 = list1 |
❌ No — same object! |
💡 When does copying matter in real life? In data science, you often need to process a dataset without destroying the original. A researcher might copy their raw data before cleaning it, so the original stays intact for verification.
Part 4 — Practice Exercise
Scenario: You have a roster of students. You want to create a “backup” roster before making changes.
original_roster = ["Alice", "Bob", "Charlie", "Diana"]
backup_roster = original_roster.copy()
# Enroll a new student in the working copy
original_roster.append("Eve")
print("Current roster:", original_roster)
print("Backup roster: ", backup_roster)
Expected Output:
Current roster: ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
Backup roster: ['Alice', 'Bob', 'Charlie', 'Diana']
Part 5 — Joining / Concatenating Lists
5.1 What Is Joining?
Joining (also called concatenating) two or more lists means combining them into one single list. All items from both lists appear together.
Real-world example: You manage two warehouses. Warehouse A has one inventory list, Warehouse B has another. To get the combined inventory, you join the two lists.
5.2 Method 1 — The + Operator
The simplest way to join two lists is to add them with +:
Example 32:
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]
list3 = list1 + list2
print(list3)
Expected Output:
['a', 'b', 'c', 1, 2, 3]
💡 This creates a new combined list.
list1andlist2are unchanged.
Example 33 — Joining three lists:
fruits = ["apple", "banana"]
veggies = ["carrot", "spinach"]
grains = ["rice", "oats"]
all_foods = fruits + veggies + grains
print(all_foods)
Expected Output:
['apple', 'banana', 'carrot', 'spinach', 'rice', 'oats']
5.3 Method 2 — The .extend() Method
.extend() adds all items from one list directly into another list (modifies the first list in place):
Example 34:
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]
list1.extend(list2)
print(list1)
Expected Output:
['a', 'b', 'c', 1, 2, 3]
🤔 What is the difference between
+and.extend()?
+creates a brand new list, leaving both originals unchanged..extend()modifieslist1by adding items fromlist2into it.
Example 35 — Adding a tuple to a list with .extend():
.extend() accepts any iterable (list, tuple, set, range, etc.), not just lists:
list1 = ["apple", "banana", "cherry"]
tuple1 = ("kiwi", "orange")
list1.extend(tuple1)
print(list1)
Expected Output:
['apple', 'banana', 'cherry', 'kiwi', 'orange']
5.4 Method 3 — A Loop with .append()
You can also join lists manually using a loop:
Example 36:
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]
for x in list2:
list1.append(x)
print(list1)
Expected Output:
['a', 'b', 'c', 1, 2, 3]
💡 This works but
.extend()is more concise and faster. Use the loop approach when you need to filter or transform items during the join.
5.5 Joining Summary
| Method | Code | Modifies original? | Use when |
|---|---|---|---|
+ operator |
c = a + b |
❌ No | You want a new list |
.extend() |
a.extend(b) |
✅ Yes (adds to a) |
You want to grow one list |
Loop + .append() |
for x in b: a.append(x) |
✅ Yes | You need to filter/transform during join |
Part 5 — Practice Exercise
Scenario: You manage two event guest lists. Combine them into one master list.
vip_guests = ["Alice", "Bob", "Charlie"]
general_guests = ["Diana", "Eve", "Frank"]
# Method 1: using +
master_list = vip_guests + general_guests
print("Master list:", master_list)
# Method 2: using .extend()
vip_guests.extend(general_guests)
print("VIP list extended:", vip_guests)
Expected Output:
Master list: ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
VIP list extended: ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
Part 6 — All Python List Methods
Python lists come with a powerful built-in toolbox of methods. Here is a complete reference guide for every method, with explanations and examples.
Overview Table
| Method | What It Does |
|---|---|
append() |
Adds one item to the end |
clear() |
Removes all items |
copy() |
Returns a copy of the list |
count() |
Counts how many times a value appears |
extend() |
Adds all items from another iterable to the end |
index() |
Returns the index of the first occurrence of a value |
insert() |
Inserts an item at a specified position |
pop() |
Removes and returns the item at a specified index |
remove() |
Removes the first occurrence of a specified value |
reverse() |
Reverses the order of the list |
sort() |
Sorts the list |
6.1 append() — Add One Item to the End
What it does: Adds a single item to the very end of the list.
Syntax: list.append(item)
Example 37:
thislist = ["apple", "banana", "cherry"]
thislist.append("orange")
print(thislist)
Expected Output:
['apple', 'banana', 'cherry', 'orange']
⚠️ Common mistake: Appending a list inside a list:
thislist.append(["orange", "grape"]) # This adds ONE item that is itself a list: ['apple', 'banana', 'cherry', ['orange', 'grape']] # Use .extend() if you want to add multiple items separately
6.2 clear() — Remove All Items
What it does: Empties the list completely. The list object still exists, it just has no items.
Syntax: list.clear()
Example 38:
thislist = ["apple", "banana", "cherry"]
thislist.clear()
print(thislist)
Expected Output:
[]
6.3 copy() — Return a Copy
Already covered in Part 4. Quick reminder:
Example 39:
thislist = ["apple", "banana", "cherry"]
mylist = thislist.copy()
print(mylist)
Expected Output:
['apple', 'banana', 'cherry']
6.4 count() — Count Occurrences of a Value
What it does: Returns how many times a specific value appears in the list.
Syntax: list.count(value)
Example 40:
thislist = [1, 4, 2, 9, 7, 8, 9, 3, 1]
print(thislist.count(9))
Expected Output:
2
Real-world use: A weather analyst might count how many days in a month the temperature exceeded 30°C.
temps = [28, 31, 33, 29, 35, 30, 33, 32, 31, 33]
print("Days above 30:", temps.count(31) + temps.count(32) + temps.count(33) + temps.count(35))
💡 For more complex counting conditions, use a loop or comprehension instead.
6.5 extend() — Add Items from Another Iterable
Already covered in Part 5. Quick reminder:
Example 41:
thislist = ["apple", "banana", "cherry"]
thislist.extend(["kiwi", "orange"])
print(thislist)
Expected Output:
['apple', 'banana', 'cherry', 'kiwi', 'orange']
6.6 index() — Find the Position of a Value
What it does: Returns the index (position) of the first occurrence of a specified value.
Syntax: list.index(value)
Example 42:
thislist = ["apple", "banana", "cherry"]
print(thislist.index("cherry"))
Expected Output:
2
Example 43 — Search within a range:
You can optionally pass a start and end position: list.index(value, start, end)
fruits = ["apple", "banana", "cherry", "banana", "kiwi"]
print(fruits.index("banana")) # First banana is at index 1
print(fruits.index("banana", 2)) # Search from index 2 onwards — finds banana at index 3
Expected Output:
1
3
⚠️ Common mistake: If the value does not exist,
.index()raises aValueError. Use this carefully or check first withif value in list.
6.7 insert() — Add an Item at a Specific Position
What it does: Inserts an item at the index you specify. All existing items at and after that index shift one position to the right.
Syntax: list.insert(index, item)
Example 44:
thislist = ["apple", "banana", "cherry"]
thislist.insert(1, "orange")
print(thislist)
Expected Output:
['apple', 'orange', 'banana', 'cherry']
"orange" was inserted at index 1. "banana" moved from index 1 to index 2. "cherry" moved from index 2 to index 3.
Example 45 — Insert at the beginning:
thislist = ["banana", "cherry"]
thislist.insert(0, "apple")
print(thislist)
Expected Output:
['apple', 'banana', 'cherry']
6.8 pop() — Remove and Return an Item by Index
What it does: Removes the item at the specified index and returns it (so you can use the removed item). If no index is given, it removes and returns the last item.
Syntax: list.pop(index) or list.pop()
Example 46 — Pop the last item:
thislist = ["apple", "banana", "cherry"]
removed = thislist.pop()
print("Removed:", removed)
print("List now:", thislist)
Expected Output:
Removed: cherry
List now: ['apple', 'banana']
Example 47 — Pop a specific index:
thislist = ["apple", "banana", "cherry"]
removed = thislist.pop(1)
print("Removed:", removed)
print("List now:", thislist)
Expected Output:
Removed: banana
List now: ['apple', 'cherry']
💡 Real-world use:
pop()is commonly used in “stack” data structures — like a pile of plates where you always take from the top. Eachpop()removes the most recently added item.
6.9 remove() — Remove an Item by Value
What it does: Finds the first occurrence of the specified value and removes it. Unlike pop(), you give it a value, not an index.
Syntax: list.remove(value)
Example 48:
thislist = ["apple", "banana", "cherry"]
thislist.remove("banana")
print(thislist)
Expected Output:
['apple', 'cherry']
Example 49 — Removes only the FIRST occurrence:
thislist = ["apple", "banana", "cherry", "banana"]
thislist.remove("banana")
print(thislist)
Expected Output:
['apple', 'cherry', 'banana']
Only the first "banana" was removed. The second one remains.
⚠️ Common mistake: If the value does not exist in the list,
remove()raises aValueError. Check first withif value in listif you are not sure.
6.10 reverse() — Reverse the List In-Place
Already covered in Part 3. Quick reminder:
Example 50:
fruits = ["apple", "banana", "cherry"]
fruits.reverse()
print(fruits)
Expected Output:
['cherry', 'banana', 'apple']
6.11 sort() — Sort the List In-Place
Already covered in Part 3. Quick reminder:
Example 51:
cars = ["Ford", "BMW", "Volvo"]
cars.sort()
print(cars)
Expected Output:
['BMW', 'Ford', 'Volvo']
6.12 Method Chaining — Can You Chain List Methods?
Most list methods return None (they modify in place), so you cannot chain them like string methods. This is a common beginner mistake:
# WRONG — .sort() returns None, so you'd be printing None
result = thislist.sort()
print(result) # Prints: None
# CORRECT — sort first, then print the list itself
thislist.sort()
print(thislist)
Part 7 — List Exercises (Practice Section)
The following exercises are inspired by the W3Schools Python Lists exercises. Work through each one, attempt it yourself, then check the solution.
Exercise 1 — Print the Second Item
Task: Print the second item in the list fruits = ["apple", "banana", "cherry"].
fruits = ["apple", "banana", "cherry"]
print(fruits[1])
Expected Output:
banana
Exercise 2 — Change the Third Item
Task: Change the third item in the list fruits from "cherry" to "watermelon".
fruits = ["apple", "banana", "cherry"]
fruits[2] = "watermelon"
print(fruits)
Expected Output:
['apple', 'banana', 'watermelon']
Exercise 3 — Find the Length
Task: Print the number of items in the list fruits.
fruits = ["apple", "banana", "cherry"]
print(len(fruits))
Expected Output:
3
Exercise 4 — Add an Item
Task: Use the correct method to add "orange" to the list fruits.
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
print(fruits)
Expected Output:
['apple', 'banana', 'cherry', 'orange']
Exercise 5 — Remove an Item
Task: Use the correct method to remove "banana" from the list.
fruits = ["apple", "banana", "cherry"]
fruits.remove("banana")
print(fruits)
Expected Output:
['apple', 'cherry']
Exercise 6 — Loop and Print
Task: Use a for loop to print every item in the list.
fruits = ["apple", "banana", "cherry"]
for x in fruits:
print(x)
Expected Output:
apple
banana
cherry
Exercise 7 — Sort Alphabetically
Task: Use the correct method to sort the list cars alphabetically.
cars = ["Porsche", "BMW", "Volvo", "Audi"]
cars.sort()
print(cars)
Expected Output:
['Audi', 'BMW', 'Porsche', 'Volvo']
Exercise 8 — Copy a List
Task: Use the correct method to copy the list fruits into a variable called mylist.
fruits = ["apple", "banana", "cherry"]
mylist = fruits.copy()
print(mylist)
Expected Output:
['apple', 'banana', 'cherry']
Part 8 — Mini Project: Student Grade Manager
Project Overview
You will build a Student Grade Manager that stores student names and their exam scores, then uses all the skills from this lesson to analyse and display results.
Skills used: loops, list comprehension, sorting, copying, joining, and list methods.
Stage 1 — Setup: Create Your Data
# Student names and their scores
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]
scores = [72, 45, 88, 91, 33, 67]
Stage 2 — Loop Through and Display Results
print("=== Grade Report ===")
for i in range(len(students)):
print(students[i] + ": " + str(scores[i]))
Expected Output:
=== Grade Report ===
Alice: 72
Bob: 45
Charlie: 88
Diana: 91
Eve: 33
Frank: 67
Stage 3 — Use List Comprehension to Identify Passing Students
A passing score is 50 or above.
passing = [students[i] for i in range(len(students)) if scores[i] >= 50]
failing = [students[i] for i in range(len(students)) if scores[i] < 50]
print("\nPassing students:", passing)
print("Failing students:", failing)
Expected Output:
Passing students: ['Alice', 'Charlie', 'Diana', 'Eve...']
Failing students: ['Bob', 'Eve']
Wait — let’s check: Eve scored 33, so she fails. Bob scored 45, so he fails. Let’s verify:
Alice 72 ✅ Bob 45 ❌ Charlie 88 ✅ Diana 91 ✅ Eve 33 ❌ Frank 67 ✅
Passing students: ['Alice', 'Charlie', 'Diana', 'Frank']
Failing students: ['Bob', 'Eve']
Stage 4 — Sort the Scores (Keep a Copy of Original)
scores_copy = scores.copy()
scores_copy.sort()
print("\nScores lowest to highest:", scores_copy)
print("Original scores unchanged:", scores)
Expected Output:
Scores lowest to highest: [33, 45, 67, 72, 88, 91]
Original scores unchanged: [72, 45, 88, 91, 33, 67]
Stage 5 — Add a New Class and Join Lists
A new class of students just joined. Join the two groups.
new_students = ["Grace", "Hank"]
new_scores = [80, 55]
all_students = students + new_students
all_scores = scores + new_scores
print("\nAll students:", all_students)
print("All scores: ", all_scores)
Expected Output:
All students: ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank']
All scores: [72, 45, 88, 91, 33, 67, 80, 55]
Stage 6 — Final Summary Using Methods
print("\n=== Summary ===")
print("Total students:", len(all_students))
print("Highest score: ", max(all_scores))
print("Lowest score: ", min(all_scores))
print("Top scorer: ", all_students[all_scores.index(max(all_scores))])
print("Needs support: ", all_students[all_scores.index(min(all_scores))])
Expected Output:
=== Summary ===
Total students: 8
Highest score: 91
Lowest score: 33
Top scorer: Diana
Needs support: Eve
Stage 7 — Complete Project Code
# ===== Student Grade Manager =====
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]
scores = [72, 45, 88, 91, 33, 67]
# --- Grade Report ---
print("=== Grade Report ===")
for i in range(len(students)):
print(students[i] + ": " + str(scores[i]))
# --- Pass/Fail ---
passing = [students[i] for i in range(len(students)) if scores[i] >= 50]
failing = [students[i] for i in range(len(students)) if scores[i] < 50]
print("\nPassing students:", passing)
print("Failing students:", failing)
# --- Sorted Copy ---
scores_copy = scores.copy()
scores_copy.sort()
print("\nScores (sorted):", scores_copy)
# --- Join New Class ---
new_students = ["Grace", "Hank"]
new_scores = [80, 55]
all_students = students + new_students
all_scores = scores + new_scores
# --- Summary ---
print("\n=== Summary ===")
print("Total students:", len(all_students))
print("Highest score: ", max(all_scores))
print("Lowest score: ", min(all_scores))
print("Top scorer: ", all_students[all_scores.index(max(all_scores))])
print("Needs support: ", all_students[all_scores.index(min(all_scores))])
🚀 Optional Extension Challenges:
- Calculate and display the class average.
- Add a letter grade (A, B, C, D, F) next to each score using a comprehension.
- Sort students by score from highest to lowest and display a ranked leaderboard.
Part 9 — Common Beginner Mistakes (Full Reference)
| Mistake | Wrong Code | Why It’s Wrong | Correct Code |
|---|---|---|---|
| Modifying list while looping | for x in lst: lst.remove(x) |
Skips items because list shrinks | Loop over a copy: for x in lst.copy() |
Forgetting i += 1 in while |
while i < len(lst): print(lst[i]) |
Infinite loop | Add i += 1 inside the loop |
= instead of .copy() |
b = a |
Both point to same list | b = a.copy() |
| Appending a list instead of extending | a.append([1,2]) |
Adds [1,2] as one nested item |
a.extend([1,2]) |
Sorting returns None |
result = lst.sort(); print(result) |
.sort() returns None |
lst.sort(); print(lst) |
.index() on missing value |
lst.index("x") when x not in lst |
Raises ValueError |
Check first: if "x" in lst: |
if/else in wrong comprehension position |
[x for x in lst if x != "a" else "b"] |
SyntaxError |
[x if x != "a" else "b" for x in lst] |
Forgetting range() vs len() |
for i in len(lst): |
len() returns an int, not iterable |
for i in range(len(lst)): |
Part 10 — Reflection Questions
Think through each of these questions. Try to answer them without looking at your notes first.
-
What is the difference between a
forloop and awhileloop? When would you prefer one over the other? -
In a list comprehension, where does the
iffilter go? Where does theif/elseexpression go? Why can’t they be in the same place? -
Why does
list2 = list1not create a true copy? What actually happens in memory? -
What is the difference between
.sort()andsorted()? When would you use each one? -
What is the difference between
.append()and.extend()? What happens if you append a list instead of extending? -
You call
.pop()on a list with no argument. What happens? What does it return? -
If you call
.sort()on a list and then try to print the return value, what do you see? Why? -
Can you think of a real-world scenario where you would need to: (a) loop through a list, (b) copy a list, (c) join two lists?
Completion Checklist
Before moving to the next lesson, make sure you can confidently tick off each item:
- I can loop through a list using a
forloop - I can loop through a list using a
whileloop with an index - I understand what
breakandcontinuedo inside a loop - I can write a basic list comprehension without a condition
- I can write a list comprehension with an
iffilter - I can write a list comprehension with an
if/elsein the expression - I can sort a list alphabetically and numerically with
.sort() - I can sort in reverse order with
reverse=True - I can perform a case-insensitive sort with
key=str.lower - I understand the difference between
.sort()andsorted() - I know why
list2 = list1is NOT a copy - I can make a safe copy using
.copy(),list(), or[:] - I can join two lists using
+and.extend() - I know what every list method does:
append,clear,copy,count,extend,index,insert,pop,remove,reverse,sort - I completed the Student Grade Manager mini-project
Lesson Summary
Here is a quick-reference summary of everything covered in Lesson 08:
Looping
# for loop — direct
for x in mylist:
print(x)
# for loop — by index
for i in range(len(mylist)):
print(mylist[i])
# while loop
i = 0
while i < len(mylist):
print(mylist[i])
i += 1
List Comprehension
# Basic
newlist = [x for x in mylist]
# With filter
newlist = [x for x in mylist if x != "apple"]
# With transformation
newlist = [x.upper() for x in mylist]
# With if/else in expression
newlist = [x if x != "banana" else "orange" for x in mylist]
Sorting
mylist.sort() # A to Z, smallest to largest
mylist.sort(reverse=True) # Z to A, largest to smallest
mylist.sort(key=str.lower) # Case-insensitive sort
sorted_copy = sorted(mylist) # Returns new list, original unchanged
mylist.reverse() # Reverses current order
Copying
copy1 = mylist.copy() # Method 1
copy2 = list(mylist) # Method 2
copy3 = mylist[:] # Method 3
# NEVER: copy4 = mylist ← this is NOT a copy!
Joining
combined = list1 + list2 # New list
list1.extend(list2) # Adds list2 into list1
All List Methods
mylist.append(item) # Add to end
mylist.clear() # Empty the list
mylist.copy() # Return a copy
mylist.count(value) # Count occurrences
mylist.extend(iterable) # Add all from iterable
mylist.index(value) # Find position of value
mylist.insert(index, item) # Insert at position
mylist.pop(index) # Remove and return by index
mylist.remove(value) # Remove first occurrence by value
mylist.reverse() # Reverse in place
mylist.sort() # Sort in place
🎉 Congratulations! You have completed Lesson 08. You now have a complete toolkit for working with Python lists at a professional level. In the next lesson, you will explore Python Tuples — a close cousin of the list with some important differences.