Imagine you are keeping track of your five favourite fruits. You could store each one in a separate variable:
fruit1 = "apple"
fruit2 = "banana"
fruit3 = "cherry"
fruit4 = "mango"
fruit5 = "grape"That works · but what if you had 500 fruits? Or what if the number of fruits changes every day? Creating 500 individual variables would be a nightmare.
Python solves this with a list · a single container that can hold as many items as you need, all under one name. Lists are one of the most important and most-used tools in all of Python. You will use them in data analysis, web development, automation, science, games, finance, and almost every real-world Python project.
By the end of this lesson you will be able to:
- Create lists and understand exactly what they are
- Access any item in a list using its index number
- Change items that are already in a list
- Add new items to a list
- Remove items from a list
- Build a working mini-project that uses all five skills together
Before we start, here are the small things you need to already know. If any of these feel unfamiliar, re-read your earlier lessons first.
| Concept | Quick reminder |
|---|---|
| Variables | name = "Alice" · a labelled box that stores a value |
print() | Displays output to the screen |
| Data types | str (text), int (whole number), float (decimal), bool (True/False) |
len() | Counts how many characters are in a string · we will use it to count list items today |
No other prior knowledge is needed. Everything else is taught from scratch right here.
1.1 The Real-World Analogy
Think of a shopping list on paper:
1. Milk
2. Eggs
3. Bread
4. ButterEach item has a position (1st, 2nd, 3rd, 4th). You can add a new item at the bottom. You can cross off (remove) something you already bought. You can change "Butter" to "Olive Oil".
A Python list works in exactly the same way · except it lives inside your program.
1.2 The Technical Definition
A Python list is:
- An ordered collection of items (items always stay in the order you put them, unless you change that order)
- Changeable (you can add, remove, and edit items after creating the list)
- Allows duplicates (the same value can appear more than once)
- Written with square brackets
[]and items separated by commas,
1.3 Creating Your First List
Syntax:
list_name = [item1, item2, item3]Simple Example 1 · A list of fruits (strings):
fruits = ["apple", "banana", "cherry"]
print(fruits)Expected output:
['apple', 'banana', 'cherry']What happened? Python stored three text values inside one variable called
fruits. Notice the square brackets and the commas.
Simple Example 2 · A list of numbers:
scores = [95, 87, 76, 100, 60]
print(scores)Expected output:
[95, 87, 76, 100, 60]Simple Example 3 · A list of mixed data types:
Python lists can hold different types in the same list:
mixed = ["Alice", 25, True, 3.14]
print(mixed)Expected output:
['Alice', 25, True, 3.14]Thinking prompt: Why would storing different types together be useful? Imagine a student record: name (string), age (int), passed (bool), GPA (float).
1.4 How Many Items? · len()
The built-in len() function counts the number of items in a list.
fruits = ["apple", "banana", "cherry"]
print(len(fruits))Expected output:
31.5 Lists Can Hold Other Lists (Nested Lists)
A list can even contain another list inside it. This is called a nested list.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix)Expected output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]We will not go deep into nested lists today, but it is important you know they exist.
1.6 The list() Constructor
You can also create a list using the list() function:
colours = list(("red", "green", "blue"))
print(colours)Expected output:
['red', 'green', 'blue']Note: Notice the double parentheses
(( ))· the inner()creates a tuple (another collection type), andlist()converts it into a list.
1.7 List Data Type
To confirm something is a list, use type():
fruits = ["apple", "banana", "cherry"]
print(type(fruits))Expected output:
<class 'list'>2.1 What Is an Index?
Every item in a list has a position number called an index.
Analogy: Think of seats in a cinema row. Seat 0 is the first seat, seat 1 is the second, and so on.
Python indexes start at 0, not 1. This is called zero-based indexing and is used in almost all programming languages.
List: ["apple", "banana", "cherry", "mango", "grape"]
Index: 0 1 2 3 42.2 Accessing a Single Item
Use the list name followed by the index number inside square brackets:
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # First item
print(fruits[1]) # Second item
print(fruits[2]) # Third itemExpected output:
apple
banana
cherryCommon beginner mistake: Trying
fruits[3]when only 3 items exist (indexes 0, 1, 2). This causes anIndexError: list index out of range.
Corrected version:
fruits = ["apple", "banana", "cherry"]
print(len(fruits)) # 3 items → valid indexes are 0, 1, 2
print(fruits[2]) # Correct: last item
# print(fruits[3]) # WRONG: would crash2.3 Negative Indexing
Python also allows negative indexes. A negative index counts from the end of the list.
List: ["apple", "banana", "cherry"]
Neg: -3 -2 -1-1 is always the last item. -2 is second from last. And so on.
fruits = ["apple", "banana", "cherry"]
print(fruits[-1]) # Last item
print(fruits[-2]) # Second from last
print(fruits[-3]) # Third from last (same as index 0)Expected output:
cherry
banana
appleThinking prompt: When would negative indexing be more useful than positive indexing? Hint: when you always want the last few items, regardless of list length.
2.4 Range of Indexes (Slicing)
You can grab a slice (a section) of a list using a colon : inside the brackets.
Syntax:
list_name[start : end]start= the index to begin from (included)end= the index to stop before (NOT included)
fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(fruits[2:5])Expected output:
['cherry', 'orange', 'kiwi']Items at indexes 2, 3, and 4 are returned. Index 5 is the stopping point · it is NOT included.
Leaving out the start index · slice from the beginning:
fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(fruits[:4])Expected output:
['apple', 'banana', 'cherry', 'orange']Leaving out the end index · slice to the end:
fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(fruits[2:])Expected output:
['cherry', 'orange', 'kiwi', 'melon', 'mango']Negative index slicing:
fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(fruits[-4:-1])Expected output:
['orange', 'kiwi', 'melon']2.5 Checking If an Item Exists · in Keyword
Use the in keyword to check whether a specific value is present in the list:
fruits = ["apple", "banana", "cherry"]
if "banana" in fruits:
print("Yes, banana is in the list!")Expected output:
Yes, banana is in the list!if "mango" in fruits:
print("Found mango")
else:
print("mango is NOT in the list")Expected output:
mango is NOT in the list3.1 Why Would You Change a List Item?
Lists are mutable · meaning you can change their contents after creation. This is different from strings, which are immutable (once created, you cannot change individual characters).
Real-world example: A store's inventory changes daily. Items go in and out of stock. A list lets you update that data without rebuilding everything from scratch.
3.2 Changing One Item
Assign a new value directly to a specific index:
fruits = ["apple", "banana", "cherry"]
fruits[1] = "mango"
print(fruits)Expected output:
['apple', 'mango', 'cherry']Position 1 (which was "banana") is now "mango". The other items are unchanged.
3.3 Changing a Range of Items
You can replace several items at once using a slice:
fruits = ["apple", "banana", "cherry", "orange", "kiwi"]
fruits[1:3] = ["mango", "melon"]
print(fruits)Expected output:
['apple', 'mango', 'melon', 'orange', 'kiwi']Items at indexes 1 and 2 ("banana" and "cherry") were replaced with "mango" and "melon".
What if you replace a range with MORE items than the original range?
fruits = ["apple", "banana", "cherry"]
fruits[1:2] = ["mango", "melon", "grape"]
print(fruits)Expected output:
['apple', 'mango', 'melon', 'grape', 'cherry']Only index 1 ("banana") was in the slice, but it was replaced by THREE items. The list grew longer!
What if you replace a range with FEWER items?
fruits = ["apple", "banana", "cherry", "orange"]
fruits[1:3] = ["mango"]
print(fruits)Expected output:
['apple', 'mango', 'orange']"banana" and "cherry" (2 items) were replaced by only "mango" (1 item). The list shrank.
3.4 Inserting an Item Without Replacing · insert()
insert(index, value) adds a new item at a specific position without removing anything:
fruits = ["apple", "banana", "cherry"]
fruits.insert(2, "watermelon")
print(fruits)Expected output:
['apple', 'banana', 'watermelon', 'cherry']"watermelon" was inserted at position 2. "cherry" was pushed to position 3. Nothing was deleted.
4.1 The Three Ways to Add Items
| Method | What it does |
|---|---|
append(value) | Adds one item to the end of the list |
insert(index, value) | Adds one item at a specific position |
extend(iterable) | Adds multiple items from another list (or any iterable) to the end |
4.2 append() · Add to the End
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
print(fruits)Expected output:
['apple', 'banana', 'cherry', 'orange']
append()is the most commonly used method for adding items. It always places the new item at the very end.
Second example · building a list step by step:
shopping = []
shopping.append("milk")
shopping.append("eggs")
shopping.append("bread")
print(shopping)Expected output:
['milk', 'eggs', 'bread']We started with an empty list
[]and built it up one item at a time. This pattern is extremely common in real programs.
4.3 insert() · Add at a Specific Position
We already saw insert() in Part 3, but here it is as an add operation:
fruits = ["apple", "banana", "cherry"]
fruits.insert(1, "kiwi")
print(fruits)Expected output:
['apple', 'kiwi', 'banana', 'cherry']"kiwi" was inserted at position 1. Everything from position 1 onwards was shifted right by one.
Insert at the beginning (position 0):
fruits = ["apple", "banana", "cherry"]
fruits.insert(0, "strawberry")
print(fruits)Expected output:
['strawberry', 'apple', 'banana', 'cherry']4.4 extend() · Add Multiple Items from Another List
fruits = ["apple", "banana", "cherry"]
more_fruits = ["mango", "pineapple", "papaya"]
fruits.extend(more_fruits)
print(fruits)Expected output:
['apple', 'banana', 'cherry', 'mango', 'pineapple', 'papaya']Every item from
more_fruitswas added individually to the end offruits.
extend() vs append() · the key difference:
fruits = ["apple", "banana"]
# append adds the whole list AS ONE item:
fruits.append(["mango", "kiwi"])
print(fruits)Expected output:
['apple', 'banana', ['mango', 'kiwi']]fruits = ["apple", "banana"]
# extend adds each item separately:
fruits.extend(["mango", "kiwi"])
print(fruits)Expected output:
['apple', 'banana', 'mango', 'kiwi']Common beginner mistake: Using
append()when you meantextend(). The result is a nested list instead of a flat list.
extend() also works with other iterables like tuples:
fruits = ["apple", "banana", "cherry"]
fruits.extend(("kiwi", "orange"))
print(fruits)Expected output:
['apple', 'banana', 'cherry', 'kiwi', 'orange']5.1 The Ways to Remove Items
| Method / Keyword | What it does |
|---|---|
remove(value) | Removes the first occurrence of a specific value |
pop(index) | Removes the item at a specific index (default: last item) |
del list[index] | Deletes item at a specific index, or deletes the whole list |
clear() | Empties the list completely (list still exists, but has no items) |
5.2 remove() · Remove by Value
fruits = ["apple", "banana", "cherry"]
fruits.remove("banana")
print(fruits)Expected output:
['apple', 'cherry']"banana" was found and removed. The list shrank by one.
What if the value appears more than once?
remove() only deletes the first occurrence:
fruits = ["apple", "banana", "cherry", "banana", "mango"]
fruits.remove("banana")
print(fruits)Expected output:
['apple', 'cherry', 'banana', 'mango']Only the first "banana" (at index 1) was removed. The second "banana" (originally at index 3) remains.
What if the value does not exist?
fruits = ["apple", "banana", "cherry"]
fruits.remove("mango") # "mango" is not in the listExpected output:
ValueError: list.remove(x): x not in listCommon beginner mistake: Calling
remove()on a value that is not in the list. Always check first withinif you are unsure.
Safe version:
fruits = ["apple", "banana", "cherry"]
if "mango" in fruits:
fruits.remove("mango")
else:
print("mango was not found in the list")Expected output:
mango was not found in the list5.3 pop() · Remove by Index
pop() removes and returns the item at a given index. If no index is given, it removes the last item.
fruits = ["apple", "banana", "cherry"]
fruits.pop(1)
print(fruits)Expected output:
['apple', 'cherry']pop() without an index · removes the last item:
fruits = ["apple", "banana", "cherry"]
fruits.pop()
print(fruits)Expected output:
['apple', 'banana']pop() returns the removed item · you can store it:
fruits = ["apple", "banana", "cherry"]
removed = fruits.pop(1)
print("Removed:", removed)
print("List now:", fruits)Expected output:
Removed: banana
List now: ['apple', 'cherry']This is very useful when you want to process the item you are removing.
5.4 del · Delete by Index or Slice
The del keyword deletes an item at a specific index:
fruits = ["apple", "banana", "cherry"]
del fruits[0]
print(fruits)Expected output:
['banana', 'cherry']Delete a slice:
fruits = ["apple", "banana", "cherry", "orange", "kiwi"]
del fruits[1:3]
print(fruits)Expected output:
['apple', 'orange', 'kiwi']Delete the entire list variable:
fruits = ["apple", "banana", "cherry"]
del fruits
# print(fruits) # This would now cause a NameError — the variable no longer existsAfter
del fruits, the variablefruitsis completely gone from memory. This is different fromclear().
5.5 clear() · Empty the List
clear() removes all items from the list, but the list variable itself still exists:
fruits = ["apple", "banana", "cherry"]
fruits.clear()
print(fruits)Expected output:
[]The list is now empty
[], butfruitsstill exists as a variable. You can add new items to it later.
Exercise 1 · Class Register
Objective: Create and display a list of student names.
Scenario: You are a teacher building a digital class register.
Steps:
- Create a list called
studentswith five student names. - Print the full list.
- Print just the first student.
- Print just the last student using negative indexing.
- Print the number of students using
len().
Starter code:
students = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
# Your code below:Expected output:
['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
Alice
Eve
5Self-check questions:
- What index does "Charlie" have?
- What would
students[-2]return? - What would
students[1:4]return?
Exercise 2 · Shopping Cart
Objective: Practice adding and removing items from a list.
Scenario: You are building a simple shopping cart.
Steps:
- Start with an empty list called
cart. - Use
append()to add: "milk", "eggs", "bread", "cheese". - Print the cart.
- The customer changed their mind · remove "eggs" using
remove(). - Add "yoghurt" at position 1 using
insert(). - Print the final cart.
- Print the total number of items.
Expected output:
['milk', 'eggs', 'bread', 'cheese']
['milk', 'yoghurt', 'bread', 'cheese']
4Optional what-if challenge: What would happen if you used pop(0) instead of remove("eggs")?
Exercise 3 · Temperature Log
Objective: Practice slicing and modifying a list.
Scenario: A weather station recorded temperatures for a week (in °C).
temperatures = [22, 19, 25, 30, 28, 17, 21]
# Days: Mon Tue Wed Thu Fri Sat SunTasks:
- Print the temperature for Wednesday (index 2).
- Print temperatures for Tuesday to Friday (use slicing).
- The Saturday reading was wrong · it should be 20. Fix it.
- Print the updated list.
- Check whether the temperature 30 is in the list and print a message.
Expected output:
25
[19, 25, 30, 28]
[22, 19, 25, 30, 28, 20, 21]
30 degrees was recorded this week.Exercise 4 · Combining Two Inventories
Objective: Practice using extend().
Scenario: Two warehouses need to merge their stock lists.
warehouse_a = ["screws", "bolts", "nails"]
warehouse_b = ["hammers", "drills", "saws"]- Use
extend()to mergewarehouse_bintowarehouse_a. - Print the combined list.
- Use
delto remove "bolts" by index. - Print the final list.
Expected output:
['screws', 'bolts', 'nails', 'hammers', 'drills', 'saws']
['screws', 'nails', 'hammers', 'drills', 'saws']Mistake 1 · IndexError: Index Out of Range
# WRONG
fruits = ["apple", "banana", "cherry"]
print(fruits[3]) # Only indexes 0, 1, 2 exist!IndexError: list index out of rangeFix: Remember that a list of n items has indexes 0 to n-1. Use len(fruits) - 1 for the last valid index.
Mistake 2 · Confusing append() and extend()
# WRONG – adds nested list
fruits = ["apple", "banana"]
fruits.append(["cherry", "mango"])
print(fruits) # ['apple', 'banana', ['cherry', 'mango']]Fix: Use extend() when you want to add multiple items individually:
fruits = ["apple", "banana"]
fruits.extend(["cherry", "mango"])
print(fruits) # ['apple', 'banana', 'cherry', 'mango']Mistake 3 · remove() on a Non-Existent Value
# WRONG
fruits = ["apple", "banana"]
fruits.remove("grape") # ValueError!Fix: Check first with in:
if "grape" in fruits:
fruits.remove("grape")Mistake 4 · Forgetting That Slicing Does NOT Include the End Index
fruits = ["apple", "banana", "cherry", "orange"]
print(fruits[1:3]) # Returns items at index 1 AND 2 — NOT 3['banana', 'cherry']The slice
[1:3]means "from index 1 up to but NOT including index 3".
Mistake 5 · del vs clear() vs Setting to []
fruits = ["apple", "banana"]
# del removes the variable entirely
del fruits
# print(fruits) # NameError — 'fruits' does not exist!
# clear() empties the list, but the variable still exists
fruits = ["apple", "banana"]
fruits.clear()
print(fruits) # [] — variable exists, just empty
# Assigning [] replaces the list with a new empty one
fruits = ["apple", "banana"]
fruits = []
print(fruits) # []Mistake 6 · Modifying a List While Looping Over It
This is an advanced mistake to be aware of. Avoid removing items from a list inside a for loop that is iterating over the same list · it causes unexpected behaviour. Use a copy or a different approach.
Project Overview
You will build a Student Grade Tracker · a small Python program that stores student names and their exam scores, allows grade updates, adds new students, and removes students who have withdrawn.
This project uses every skill from today's lesson.
Stage 1 · Setup
Create two lists: one for student names, one for their scores. Each index position corresponds to the same student.
# Stage 1 – Create the lists
names = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
scores = [88, 74, 91, 65, 83]
print("Students:", names)
print("Scores: ", scores)
print("Total students:", len(names))Lesson 07 complete! 🎉
You covered:
- ✅ Lesson Introduction
- ✅ Prerequisite Concepts
- ✅ Part 1 · What Is a Python List?
- ✅ Part 2 · Accessing List Items
- ✅ Part 3 · Changing List Items
- ✅ Part 4 · Adding Items to a List
- ✅ Part 5 · Removing Items from a List
- ✅ Part 6 · Guided Practice Exercises