1. The Big Picture: Why Do Lists Exist?
Suppose you need to store five test scores.
score1 = 85
score2 = 92
score3 = 78
score4 = 91
score5 = 88
This works, but what happens when there are 500 scores? What if you need to calculate an average? Find the highest score? Process every score?
You need a way to store many related values under one variable name.
scores = [85, 92, 78, 91, 88]
Now one variable represents the entire collection.
Which is easier to process with a loop?
score1 = 85
score2 = 92
score3 = 78
score4 = 91
score5 = 88
or:
scores = [85, 92, 78, 91, 88]
The important idea is not the brackets. The important idea is collection + repetition.
2. What Is a Python List?
numbers = [10, 20, 30, 40]
A Python list is an ordered collection of objects.
| Characteristic | What it means | Example |
|---|---|---|
| Ordered | Items have a defined position. | [10, 20, 30] |
| Mutable | Items can be changed after the list is created. | numbers[0] = 100 |
| Allows duplicates | The same value can appear multiple times. | [3, 3, 5] |
| Heterogeneous | A list can contain different object types. | [10, "Python", 3.5] |
| Dynamic | Items can be added and removed. | append() |
| Nestable | A list can contain other lists. | [[1,2], [3,4]] |
Critical Thinking
Why might a list be better than five separate variables even when the number of values is small?
Think about what happens when you want to:
- repeat an operation
- count values
- find a maximum
- filter values
- calculate statistics
3. Creating Lists
Empty list
numbers = []
List of numbers
scores = [85, 92, 78, 91]
List of strings
names = ["Ali", "Sara", "John"]
Mixed data types
student = ["Ali", 21, 3.8, True]
Nested list
matrix = [
[1, 2],
[3, 4],
[5, 6]
]
Predict
What is the length of each list?
a = []
b = [10]
c = [10, 20, 30]
d = [[1, 2], [3, 4]]
Remember: len() counts the items directly contained
in the list.
4. Accessing List Items
A list may contain many values. How do we retrieve one specific value?
Python solves this using indexing.
names = ["Ali", "Sara", "John", "Maria"]
Zero-based indexing
| Index | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| Value | Ali | Sara | John | Maria |
print(names[0]) # Ali
print(names[2]) # John
Common mistake
Students often think the first item is index 1.
names[1]
This gives Sara, not Ali.
The index represents the item's position starting from zero.
Negative indexing
print(names[-1]) # Maria
print(names[-2]) # John
Negative indexes count from the end.
Slicing
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])
The start index is included; the stop index is excluded.
Predict before running
numbers = [10, 20, 30, 40, 50]
print(numbers[0])
print(numbers[3])
print(numbers[-1])
print(numbers[1:4])
print(numbers[:3])
print(numbers[2:])
Write down the output before running the program. Then check your prediction.
5. Modifying Lists
We can retrieve an item with an index. But what if the value is wrong and needs to be changed?
Change one item
numbers = [10, 20, 30, 40]
numbers[1] = 200
print(numbers)
Change every occurrence
If the same value appears multiple times, changing one index only changes one item.
numbers = [1, 3, 5, 3, 7, 3]
numbers[1] = 300
print(numbers)
If the goal is to replace every 3, you need repetition.
numbers = [1, 3, 5, 3, 7, 3]
for i in range(len(numbers)):
if numbers[i] == 3:
numbers[i] = 300
print(numbers)
The important distinction
Ask yourself:
- Am I changing one known position?
- Am I changing every item that meets a condition?
The first problem needs indexing. The second problem needs repetition + a condition.
6. Adding and Removing Items
append()
Use append() when you want to add one item to the end.
fruits = ["apple", "banana"]
fruits.append("mango")
print(fruits)
insert()
fruits.insert(1, "orange")
Insert adds an item at a specific position.
remove()
fruits.remove("banana")
Removes the first matching value.
pop()
last_item = fruits.pop()
Removes and returns an item.
del
del fruits[1]
Deletes an item using its index.
| Operation | Use it when... |
|---|---|
append() |
You want to add one item to the end. |
insert() |
You want to add an item at a particular position. |
remove() |
You know the value you want to remove. |
pop() |
You want to remove an item and possibly use the removed value. |
del |
You want to delete using an index. |
Common Error: confusing remove() and pop()
numbers.remove(2)
This means: remove the value 2.
numbers.pop(2)
This means: remove the item at index 2.
7. Useful Built-in Functions
scores = [85, 92, 78, 91, 88]
print(len(scores))
print(sum(scores))
print(max(scores))
print(min(scores))
print(sorted(scores))
| Function | Purpose |
|---|---|
len() |
Number of items |
sum() |
Total of numeric items |
max() |
Largest item |
min() |
Smallest item |
sorted() |
Returns a new sorted list |
Error-driven learning: "int object is not callable"
Suppose you write:
sum = 100
print(sum(scores))
You may see:
TypeError: 'int' object is not callable
Why?
You accidentally used the name sum for a variable.
Python can no longer access the built-in sum() function
through that name.
Avoid variable names such as:
sum
list
str
int
len
max
min
8. Lists + for Loops
The problem
You have a list containing 1,000 values. You want to perform the same operation on every value. Writing 1,000 statements is not realistic.
A loop lets the program repeat the operation.
Loop directly through values
names = ["Ali", "Sara", "John"]
for name in names:
print(name)
Use this approach when you care about the values.
Process every number
numbers = [3, 7, 10, 12]
for number in numbers:
print(number ** 2)
Counting with a loop
scores = [85, 62, 91, 48, 77, 55, 93]
count = 0
for score in scores:
if score >= 70:
count += 1
print(count)
Recognize the pattern
Many list problems follow this structure:
for item in list:
if condition:
do_something()
This is the basic pattern behind:
- counting
- filtering
- searching
- calculating totals
- building new lists
9. Index + Loop: When Position Matters
Sometimes you don't just need the value. You need to know where the value is.
Example: names and scores
names = ["Ali", "Sara", "John", "Maria"]
scores = [85, 92, 78, 88]
for i in range(len(names)):
print(names[i], "->", scores[i])
Here, the same index connects the two lists.
| Index | names | scores |
|---|---|---|
| 0 | Ali | 85 |
| 1 | Sara | 92 |
| 2 | John | 78 |
| 3 | Maria | 88 |
Important question
Why not simply write:
for name in names:
for score in scores:
print(name, score)
Because the inner loop creates every possible combination. It does not preserve the one-to-one relationship between the two lists.
10. Nested Lists
What if one list is not enough to represent the structure of your data?
Consider a spreadsheet:
1 2
3 4
5 6
A natural Python representation is:
matrix = [
[1, 2],
[3, 4],
[5, 6]
]
This is a list containing lists.
Accessing nested items
print(matrix[0][0]) # 1
print(matrix[1][1]) # 4
print(matrix[2][0]) # 5
Think of it as:
matrix[row][column]
Nested loops
for i in range(len(matrix)):
for j in range(len(matrix[i])):
print(matrix[i][j])
Trace the loop
For this matrix:
matrix = [
[1, 2],
[3, 4],
[5, 6]
]
Ask:
- What is the first value of
i? - What is the first value of
j? - What does
matrix[i][j]become? - When does the inner loop finish?
- When does
ichange?
Row totals
matrix = [
[3, 8, 2],
[10, 5, 7],
[4, 12, 6]
]
for row in matrix:
total = 0
for number in row:
total += number
print(total)
Notice that we did not need indexes here.
When you only need the values, looping directly through the values is often simpler.
11. List Comprehensions
Why do we need them?
Suppose you want to create a new list by transforming every item in another list.
The normal loop is:
numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
squares.append(number ** 2)
Python provides a compact way to express the same pattern.
squares = [number ** 2 for number in numbers]
The basic pattern
[expression for item in iterable]
Read it conceptually as:
"For each item, calculate this expression and put the result into a new list."
Transformation
numbers = [1, 2, 3, 4]
doubled = [n * 2 for n in numbers]
Filtering
numbers = [3, 15, 8, 22, 4, 30]
large = [n for n in numbers if n > 10]
Do not memorize the syntax blindly
Start with the normal loop:
result = []
for n in numbers:
if n > 10:
result.append(n)
Then identify:
- What am I putting into the new list?
- Where does each item come from?
- Which items should be included?
Then translate it into:
[n for n in numbers if n > 10]
Flattening a nested list
matrix = [
[1, 2],
[3, 4],
[5, 6]
]
flat = [number for row in matrix for number in row]
print(flat)
Read nested comprehensions carefully
[number for row in matrix for number in row]
A good strategy is to expand it back into ordinary loops when you are unsure:
result = []
for row in matrix:
for number in row:
result.append(number)
If you cannot explain the ordinary loop, you probably should not write the comprehension yet.
12. Debugging Lists
A strong programmer does not try to avoid every error. A strong programmer learns how to read and investigate errors.
Error 1: Index out of range
numbers = [10, 20, 30]
print(numbers[3])
There is no index 3. The valid indexes are:
0, 1, 2
The list has length 3, but its last index is 2.
Error 2: Modifying while looping incorrectly
Changing the size of a list while iterating over it can create unexpected behavior.
For example, repeatedly removing items from the same list while moving through it requires careful reasoning.
When possible, consider creating a new list instead.
Error 3: Using parentheses instead of brackets
numbers = (10, 20, 30)
This creates a tuple, not a list.
numbers = [10, 20, 30]
This creates a list.
Error 4: Calling a list like a function
numbers = [10, 20, 30]
print(numbers(0))
A list is indexed with square brackets:
print(numbers[0])
Error 5: Forgetting that indexing starts at zero
names = ["Ali", "Sara", "John"]
print(names[1])
The result is "Sara", not "Ali".
13. Practice: From Basic to Advanced
Level 1 — Basic
- Create a list of five favorite foods.
- Print the first item.
- Print the last item.
- Change the third item.
- Add a new item.
- Remove one item.
- Print the length.
Level 2 — Lists + Loops
- Print every item in a list.
- Print the square of every number.
- Count numbers greater than 50.
- Calculate the sum of all numbers.
- Build a list containing only even numbers.
Level 3 — Indexing
- Print names and scores side by side.
- Find the index of the highest score.
- Compare two lists item by item.
- Replace every occurrence of a value.
Level 4 — Nested Lists
- Access a specific matrix item.
- Print every matrix item.
- Calculate each row's total.
- Find the maximum value in each row.
Level 5 — List Comprehensions
- Convert a loop into a comprehension.
- Filter numbers using a comprehension.
- Convert temperatures using a comprehension.
- Flatten a nested list.
14. Critical Thinking Questions
range(len(numbers)) produce useful indexes?
15. Code Tracing Practice
Trace 1
numbers = [2, 4, 6]
total = 0
for n in numbers:
total += n
print(total)
Before running it, write down the value of total
after each loop iteration.
Trace 2
numbers = [3, 8, 12, 5]
result = []
for n in numbers:
if n > 7:
result.append(n)
print(result)
Track the contents of result after every iteration.
Trace 3 — Nested Loop
matrix = [
[1, 2],
[3, 4]
]
for row in matrix:
for number in row:
print(number)
How many times does the inner loop execute?
16. Challenge Problems
Challenge 1 — Running Sum
numbers = [2, 4, 6, 8]
Create:
[2, 6, 12, 20]
Each item represents the total accumulated up to that point.
Challenge 2 — Sum Greater Elements
numbers = [5, 12, 3, 20, 7, 15]
Calculate the sum of values greater than 10.
Challenge 3 — Common Unique Items
list1 = [1, 2, 3, 4, 5]
list2 = [3, 4, 4, 5, 6, 7]
Create a list containing values found in both lists without duplicates.
Expected:
[3, 4, 5]
Challenge 4 — Index-wise Combination
list1 = [1, 2, 3, 4]
list2 = [10, 20, 30, 40]
Create:
[11, 22, 33, 44]
Do it using indexes. Do not use zip().
Challenge 5 — Product of Digits
numbers = [123, 45, 67]
Produce:
[6, 20, 42]
Because:
123 → 1 × 2 × 3 = 6
45 → 4 × 5 = 20
67 → 6 × 7 = 42
17. 🏆 Final Challenge — Student Grade Analyzer
You are given two related lists:
students = ["Ali", "Sara", "John", "Maria", "David"]
scores = [85, 92, 67, 74, 58]
Build a program that analyzes the students' scores.
Do not start coding immediately.
First identify:
- What information do I have?
- What information do I need to calculate?
- Which tasks require a loop?
- Which tasks require an index?
- Which tasks require a new list?
- Which tasks can use a built-in function?
This is the transition from writing syntax to designing an algorithm.
18. How to Approach an Unfamiliar List Problem
Ask these questions in order:
-
What is my input?
Is it one list? Two lists? A nested list? -
What should my output look like?
One value? A count? A new list? Multiple values? -
Do I need every item?
If yes, consider a loop. -
Do I need the position?
If yes, consider an index. -
Am I selecting some items?
You probably need a condition. -
Am I creating a new collection?
Consider building a new list. -
Is the data nested?
You may need a nested loop. -
Can I clearly express the logic?
Write the ordinary loop first. -
Can I simplify it?
Only after the logic works, consider a list comprehension.
19. Python Lists — Quick Reference
| Task | Syntax |
|---|---|
| Create | numbers = [1, 2, 3] |
| Empty list | numbers = [] |
| Access | numbers[0] |
| Last item | numbers[-1] |
| Slice | numbers[1:4] |
| Length | len(numbers) |
| Change | numbers[0] = 100 |
| Add to end | numbers.append(100) |
| Insert | numbers.insert(1, 100) |
| Remove value | numbers.remove(100) |
| Remove by index | numbers.pop(1) |
| Delete by index | del numbers[1] |
| Total | sum(numbers) |
| Largest | max(numbers) |
| Smallest | min(numbers) |
| Sorted copy | sorted(numbers) |
| Loop through values | for n in numbers: |
| Loop through indexes | for i in range(len(numbers)): |
| Comprehension | [expression for item in numbers] |
| Filter comprehension | [item for item in numbers if condition] |
20. 🧠 Mastery Check
Before moving on from lists, you should be able to explain these without looking at your notes:
- □ What problem does a list solve?
- □ What does it mean for a list to be mutable?
- □ Why does Python use zero-based indexing?
- □ How do you access the last item?
- □ What is the difference between an index and a value?
- □ How do you change one item?
- □ How do you change every item that meets a condition?
- □ What is the difference between
remove()andpop()? - □ When should you loop directly through values?
- □ When do you need indexes?
- □ Why are nested loops useful with nested lists?
- □ What problem does a list comprehension solve?
- □ How do you convert a normal loop into a comprehension?
- □ How do you debug an
IndexError? - □ How can you determine what your code is doing without running it?
- □ Can you explain your algorithm before writing the code?
Final principle
Don't memorize 20 list tricks. Learn to recognize the underlying patterns.
Most list problems reduce to a small number of ideas:
Get one item.
numbers[i]
Visit every item.
for n in numbers
Keep items that meet a condition.
if condition
Turn each item into something new.
n * 2
Combine values into a result.
total += n
Work with position.
range(len(...))
Process collections inside collections.
for row ... for item ...
Build a new list.
result.append(...)
🎫 Exit Ticket
1. Explain
In your own words, what problem do Python lists solve?
2. Predict
numbers = [10, 20, 30, 40]
print(numbers[-2])
What will be printed?
3. Debug
numbers = [10, 20, 30]
print(numbers[3])
What error occurs and why?
4. Choose
When would you use:
- a direct
forloop? - an indexed
forloop? - a nested loop?
- a list comprehension?
5. Transfer
Think of something outside programming that could be represented as a list. Explain why a list is an appropriate representation.
Reference
For formal Python documentation, see the Python documentation on data structures and lists.
This revision guide is designed as instructional material rather than a replacement for the official Python documentation.