Lists and Iteration
A single country dictionary is not a country explorer. We need to hold many of them โ that means lists, indexing, and loops.
An ordered, indexed sequence of values.
1. Learning Objective
By the end of this session you will be able to:
- Create a list using literal syntax and understand that it is ordered and mutable
- Access items by index, including negative indexing
- Use len() and iterate with a for loop
- Explain the difference between mutating methods (.append, .sort) and non-mutating operations
- Store a list of dictionaries โ the shape our whole project will use
2. Pre-Coding Quiz
Answer these before reading the concept explanation or writing any code. It is fine to get these wrong โ that is the point. You need 4/5 to proceed to the lab.
You have countries = ["Kenya", "Ghana", "Peru"]. What does countries[1] return?
What does countries[-1] return for the same list?
-1 is always the last item, -2 the second-to-last, and so on. This avoids writing countries[len(countries) - 1].What is printed by:nums = [3, 1, 2]
nums.append(9)
print(nums)
.append() is a mutating method โ it adds to the existing list object and returns None. It does not create a new list.You loop with for country in countries:. On each iteration, what does country refer to?
for ... in loop over a list binds the loop variable to each element's value in turn โ not the index. Use enumerate() when you need both the index and the value.You want each item in the loop to be a dictionary you can read fields from, e.g. country["name"]. What must countries be?
country["name"] to work inside the loop, each element yielded by the loop must itself be a dict. That means countries is a list whose elements are dicts โ exactly the shape we build in this session's lab.3. The Concept โ Python Lists and Iteration
Index counts up from 0 on the left, and down from -1 on the right โ both point into the same list.
What is a list?
A list is an ordered, mutable sequence of values. Unlike a dictionary, items are accessed by position (index), not by name.
countries = ["Kenya", "Ghana", "Peru"]
print(countries[0]) # "Kenya" โ first item, index 0
print(countries[1]) # "Ghana"
print(countries[-1]) # "Peru" โ last item, negative index
print(len(countries)) # 3
Iterating with a for loop
The most common way to process every item in a list is a for ... in loop. No manual index counting required.
countries = ["Kenya", "Ghana", "Peru"]
for country in countries:
print(country)
# Kenya
# Ghana
# Peru
# When you need the index too, use enumerate()
for i, country in enumerate(countries):
print(i, country)
# 0 Kenya
# 1 Ghana
# 2 Peru
Mutating vs non-mutating operations
Some list methods change the list in place and return None. Others return a new value and leave the original untouched. Confusing the two is a very common bug.
nums = [3, 1, 2]
nums.append(9) # mutates in place -> [3, 1, 2, 9]
nums.sort() # mutates in place -> [1, 2, 3, 9]
# sorted() is non-mutating โ it returns a NEW list
original = [3, 1, 2]
result = sorted(original)
print(original) # [3, 1, 2] โ unchanged
print(result) # [1, 2, 3] โ new list
.sort() mutates the original object; sorted() leaves it alone and hands back a new list.
A list of dictionaries โ our project's core data shape
Combining what we learned in Session 05 with lists gives us exactly what a real application needs: a collection of structured records.
countries = [
{"name": "Kenya", "region": "Africa", "population": 54000000},
{"name": "Ghana", "region": "Africa", "population": 31000000},
{"name": "Peru", "region": "Americas", "population": 33000000},
]
for country in countries:
print(country["name"], "-", country["region"])
# Kenya - Africa
# Ghana - Africa
# Peru - Americas
4. Lab
What you will build
A file called countries.py that builds on Session 05's single dictionary.
Step-by-step instructions
Create the file
# countries.py
Build a list of at least 3 country dictionaries
Reuse the shape from Session 05 โ each item needs at least name, region, and population.
countries = [
{"name": "Kenya", "region": "Africa", "population": 54000000},
{"name": "Ghana", "region": "Africa", "population": 31000000},
{"name": "Peru", "region": "Americas", "population": 33000000},
]
Iterate and print each country's name
Use a plain for loop, no enumerate yet.
for country in countries:
print(country["name"])
Iterate with enumerate() to also print position
for i, country in enumerate(countries):
print(f"{i}: {country['name']}")
Add a country with .append()
Print the list before and after to confirm it mutated in place.
print("Before:", len(countries))
countries.append({"name": "Japan", "region": "Asia", "population": 125000000})
print("After:", len(countries))
Prove sorted() does not mutate
Sort the country names alphabetically without touching the original list.
names = [c["name"] for c in countries] if False else None # ignore, next session
name_list = ["Peru", "Ghana", "Kenya", "Japan"]
sorted_names = sorted(name_list)
print("Original order:", name_list)
print("Sorted copy:", sorted_names)
Access the last item with negative indexing
print("Last country added:", countries[-1]["name"])
5. Expected Files Changed
| File | Action | Why |
|---|---|---|
countries.py |
Created | Builds a list of dictionaries and demonstrates iteration. |
docs/sessions/session-06/index.html |
Created | This session document. |
6. Commit Checkpoint
Once the lab is complete and you can explain every line, make this exact commit:
git add countries.py docs/sessions/session-06/index.html
git commit -m "session-06: store countries in a list, iterate, and separate mutating from non-mutating ops"
7. Code Review Checklist
Go through your code line by line and check each item:
8. Post-Coding Quiz
Same 5 questions. Take it again now that you have written and run the code. You need 4/5 to mark this session complete.
You have countries = ["Kenya", "Ghana", "Peru"]. What does countries[1] return?
What does countries[-1] return for the same list?
-1 is always the last item, -2 the second-to-last, and so on. This avoids writing countries[len(countries) - 1].What is printed by:nums = [3, 1, 2]
nums.append(9)
print(nums)
.append() is a mutating method โ it adds to the existing list object and returns None. It does not create a new list.You loop with for country in countries:. On each iteration, what does country refer to?
for ... in loop over a list binds the loop variable to each element's value in turn โ not the index. Use enumerate() when you need both the index and the value.You want each item in the loop to be a dictionary you can read fields from, e.g. country["name"]. What must countries be?
country["name"] to work inside the loop, each element yielded by the loop must itself be a dict. That means countries is a list whose elements are dicts โ exactly the shape we build in this session's lab.9. Reflection Questions
Think through these after the post-quiz. No right answer โ they are for discussion.
- Why do you think Python chose zero-based indexing instead of starting at 1?
- If
.append()mutates in place and returnsNone, what wouldcountries = countries.append(x)incorrectly leavecountriesas? Try it. - When would negative indexing actually save you from an error-prone calculation?
- Why is "a list of dictionaries" a more useful shape than three separate parallel lists (names, regions, populations)?
10. What Breaks If This Knowledge Is Missing?
- The append-return bug: A very common beginner mistake is writing
x = some_list.append(item), expectingxto be the updated list. It is actuallyNone, because mutating methods return nothing. This trips people up for years if never explained explicitly. - List comprehensions (Session 07): The next session builds directly on for-loop iteration. If you cannot trace what a for loop does step by step, list comprehensions will look like meaningless syntax instead of a shorthand for something you already understand.
- Testing (Layer 5): Later, you will write tests that assert on list contents and order. Without understanding indexing and iteration, you cannot reason about what a test assertion is actually checking.
11. What We Learned
Python concept mastered: Lists โ indexing (including negative), len(), for-loop iteration, enumerate(), mutating vs non-mutating operations.
Unlocks: You can now hold and process a real collection of records โ the shape our whole Country Explorer project uses.
Next session: Session 07 โ List Comprehensions. We will learn to transform and filter this list without a manual for-loop, using list comprehensions.