Contents

Week 3: Data Structures — Lists, Tuples, Dictionaries and Sets

Month 1 | Main goal: The student can store and process groups of data with list, tuple, dict and set, and choose the right structure for the job.

Teacher Preparation (read before the week starts)

  • Create the folder python_darasa\wiki03.
  • Read: https://docs.python.org/3/tutorial/datastructures.html (sections 5.1, 5.3, 5.4, 5.5). Also https://docs.python.org/3/tutorial/introduction.html#lists.
  • This week has one hard concept: lists and dicts are mutable (they can change), and if you write b = a, a and b point to the very same list. Try it yourself in the REPL (Session 1, Step 6) until you understand it.
  • Practise writing the students dict (Session 3) — it will be used again in Week 4 in the "Daftari la Wanafunzi" (Student Register) project.
  • Teaching tip: draw the list boxes on a "whiteboard" (or Paint/Google Jamboard) with the index underneath each one.

Week Goals (by the end of the week the student will be able to...)

  1. Create a list, access elements by index and slicing, and change it.
  2. Use list methods: append, insert, extend, remove, pop, sort, reverse, index, count, as well as len, sum, min, max, sorted, in.
  3. Go through a list with for (including enumerate), and build a new list inside a loop.
  4. Use a tuple and understand why it cannot change; tuple unpacking.
  5. Use a dictionary: adding, changing, deleting, .get(), .keys(), .values(), .items(), looping through it, counting.
  6. Use a set: removing duplicates, union, intersection, difference.
  7. Use nested structures (a list of dicts, a dict of lists) and choose the right structure.

Session 1 — Lists: creating, index, slicing, methods

Session flow

  1. Homework review (FizzBuzz, PIN)
  2. Why do we need lists? Creating a list, len, index
  3. Slicing and changing an element
  4. Methods for adding and removing
  5. Break
  6. sort, sorted, sum, min, max, in, index, count
  7. Mutability: b = a versus b = a.copy()
  8. In-class exercise
  9. Q&A + homework

Explanation for the teacher (read this first)

  • A list is an ordered sequence of items, inside square brackets [], separated by commas: matunda = ["embe", "ndizi", "chungwa"] (fruits: mango, banana, orange).
  • It can hold any type, even a mixture: [1, "a", 2.5, True]. Empty list: [].
  • Index and slicing are exactly the same as for strings (Week 2): matunda[0], matunda[-1], matunda[0:2].
  • The big difference from a string: a list is mutable — it can be changed in place: matunda[0] = "papai" works.
  • Methods that change the list (and return None):
    • append(x) — add at the end
    • insert(i, x) — add at index i
    • extend(list2) — add all the elements of another list
    • remove(x) — remove the first x found (error if it isn't there)
    • pop() — remove and return the last item; pop(i) — the item at index i
    • sort() — sort (numbers: small→large; strings: alphabetical); sort(reverse=True)
    • reverse() — reverse the order
    • clear() — delete everything
  • Functions/methods that don't change it: len(l), sum(l), min(l), max(l), sorted(l) (returns a new sorted list), l.index(x), l.count(x), x in l.
  • The big trap: matunda = matunda.sort() → now matunda is None! Because sort() changes the list and returns None. Write matunda.sort() on its own, or mpya = sorted(matunda).
  • Mutability/aliasing: b = a doesn't make a copy; it is a second label on the same list. To make a copy: b = a.copy() or b = a[:].
  • From string to list: "a,b,c".split(",") → ['a', 'b', 'c']. From list to string: ", ".join(["a", "b"]) → "a, b".

Say this to the student

  • "So far one variable has held one thing. If you have 40 students, will you create 40 variables? No! A list is like a cabinet with ordered drawers, and each drawer has a number (index) starting from 0."
  • "A list is like a shopping list for the market: you can add something (append), cross something out (remove), put it in order (sort)."
  • "A string is like words on stone (they don't change); a list is like words in pencil (you can erase and rewrite)."
  • "b = a is like giving a friend a second key to your house — not a second house! If they move a chair, it is your house that has changed. a.copy() is building another house that looks the same."

Type this code live (share screen)

Step 1 — lists.py: creating and accessing

python
matunda = ["embe", "ndizi", "chungwa", "nanasi"]
print(matunda)            # ['embe', 'ndizi', 'chungwa', 'nanasi']
print(len(matunda))       # 4
print(matunda[0])         # embe
print(matunda[-1])        # nanasi
print(matunda[1:3])       # ['ndizi', 'chungwa']
print(type(matunda))      # <class 'list'>

Step 2 — Changing

python
matunda[0] = "papai"
print(matunda)            # ['papai', 'ndizi', 'chungwa', 'nanasi']

Step 3 — Adding

python
manunuzi = []
manunuzi.append("mchele")
manunuzi.append("sukari")
manunuzi.insert(0, "unga")
manunuzi.extend(["chumvi", "mafuta"])
print(manunuzi)    # ['unga', 'mchele', 'sukari', 'chumvi', 'mafuta']

Step 4 — Removing

python
manunuzi.remove("sukari")
print(manunuzi)            # ['unga', 'mchele', 'chumvi', 'mafuta']
cha_mwisho = manunuzi.pop()
print(cha_mwisho)          # mafuta
print(manunuzi)            # ['unga', 'mchele', 'chumvi']
cha_kwanza = manunuzi.pop(0)
print(cha_kwanza)          # unga
print(manunuzi)            # ['mchele', 'chumvi']
del manunuzi[0]
print(manunuzi)            # ['chumvi']

Step 5 — Sorting and statistics

python
alama = [67, 82, 45, 90, 73, 82]
print(len(alama), sum(alama), min(alama), max(alama))   # 6 439 45 90
print("Wastani:", round(sum(alama) / len(alama), 2))      # Wastani: 73.17
print(sorted(alama))          # [45, 67, 73, 82, 82, 90]  (mpya)
print(alama)                  # [67, 82, 45, 90, 73, 82]  (haijabadilika)
alama.sort(reverse=True)
print(alama)                  # [90, 82, 82, 73, 67, 45]
print(alama.count(82))        # 2
print(alama.index(73))        # 3
print(100 in alama)           # False

Show the trap:

python
x = [3, 1, 2]
x = x.sort()
print(x)        # None  ← tatizo!

Step 6 — Mutability (the REPL is best here)

python
>>> a = [1, 2, 3]
>>> b = a
>>> b.append(4)
>>> a
[1, 2, 3, 4]
>>> c = a.copy()
>>> c.append(5)
>>> a
[1, 2, 3, 4]
>>> c
[1, 2, 3, 4, 5]

Step 7 — split and join

python
mstari = "Dodoma,Arusha,Mwanza,Tanga"
miji = mstari.split(",")
print(miji)                    # ['Dodoma', 'Arusha', 'Mwanza', 'Tanga']
print(" | ".join(miji))        # Dodoma | Arusha | Mwanza | Tanga

namba_str = input("Weka namba zilizotenganishwa kwa nafasi: ")   # mf. 4 8 15
vipande = namba_str.split()
print(vipande)                 # ['4', '8', '15']  ← bado ni strings

Questions to ask the student

  1. l = [10, 20, 30]; l[1]? — Answer: 20.
  2. The difference between append and extend? — Answer: l.append([1,2]) adds the whole list as a single element; l.extend([1,2]) adds 1 and 2 separately.
  3. The difference between sort() and sorted()? — Answer: sort() changes the list itself and returns None; sorted() returns a new list.
  4. pop() and remove()? — Answer: pop removes by index (and returns the item); remove removes by value.
  5. After b = a; b.append(9), has a changed? — Answer: Yes, it is the same list.

Common mistakes

Mistake Error message Fix
Index out of range IndexError: list index out of range The last index is len(l) - 1.
Removing something that isn't there ValueError: list.remove(x): x not in list Check first: if x in l: l.remove(x)
pop on an empty list IndexError: pop from empty list Check if l: first.
l = l.sort() l becomes None; later TypeError: object of type 'NoneType' has no len() l.sort() on its own.
sum of strings TypeError: unsupported operand type(s) for +: 'int' and 'str' Convert to int first.
l.append(1, 2) TypeError: list.append() takes exactly one argument (2 given) l.extend([1, 2])
Sorting a mixed list TypeError: '<' not supported between instances of 'str' and 'int' Don't mix types in a list you plan to sort.

In-class exercise

  1. Create a list of 5 Tanzanian towns. Add one at the end and one at the beginning, remove the third, sort alphabetically and print.
  2. There is a list alama = [55, 78, 91, 34, 66, 78] (marks). Print: the count, total, average, highest, lowest, and the top 3 marks.
  3. Ask the user for comma-separated names; display the number of names and the names in sorted order.
Answer
python
# zoezi 1
miji = ["Dodoma", "Arusha", "Mwanza", "Tanga", "Mbeya"]
miji.append("Iringa")
miji.insert(0, "Kigoma")
miji.pop(2)          # wa tatu ni index 2 -> "Arusha"
miji.sort()
print(miji)   # ['Dodoma', 'Iringa', 'Kigoma', 'Mbeya', 'Mwanza', 'Tanga']
python
# zoezi 2
alama = [55, 78, 91, 34, 66, 78]
print("Idadi:", len(alama))
print("Jumla:", sum(alama))
print("Wastani:", round(sum(alama) / len(alama), 1))
print("Kubwa:", max(alama), "Ndogo:", min(alama))
print("Top 3:", sorted(alama, reverse=True)[:3])   # [91, 78, 78]
python
# zoezi 3
maandishi = input("Majina (tenganisha kwa koma): ")
majina = maandishi.split(",")
safi = []
for j in majina:
    safi.append(j.strip().title())
print("Idadi:", len(safi))
print("Yamepangwa:", sorted(safi))

Session 2 — Loops over Lists, and Tuples

Session flow

  1. Homework review
  2. for over a list; accumulator (total, largest)
  3. Building a new list in a loop (filter); enumerate; range(len())
  4. List comprehension (a short introduction)
  5. Break
  6. Tuples: creating, immutable, unpacking
  7. Lists inside lists (nested lists, a little)
  8. In-class exercise
  9. Q&A + homework

Explanation for the teacher (read this first)

  • for kitu in list: — kitu (item) takes each element in turn. You choose the name kitu yourself (e.g. for tunda in matunda: — a singular name for a plural list is a good habit; tunda = fruit, matunda = fruits).
  • 3 important patterns:
    1. Accumulate: jumla = 0 → for x in l: jumla += x
    2. Filter: mpya = [] → for x in l: if sharti: mpya.append(x)
    3. Transform: mpya = [] → for x in l: mpya.append(x * 2)
  • enumerate(l) gives pairs (index, kitu): for i, tunda in enumerate(matunda):. enumerate(l, start=1) starts counting at 1.
  • List comprehension is a short way of writing patterns 2 and 3: [x * 2 for x in l], [x for x in l if x > 50]. Teach it as a "shortcut"; if the student finds it hard, the long way is enough.
  • Don't change a list you are looping over (e.g. using remove inside a for over the same list) — it skips elements. Create a new list instead.
  • A tuple is like a list but cannot change (immutable), and uses parentheses (): nafasi = (6.16, 35.75) (nafasi = position). It is used for data that shouldn't change: dates, coordinates, days of the week.
    • A tuple with one element needs a comma: (5,). (5) is just an int!
    • Unpacking: lat, lon = nafasi. Also swapping: a, b = b, a.
    • Methods: only count and index.
    • Advantages: safe (it can't change by accident), and it can be a dict key (Session 3).

Say this to the student

  • "for over a list is like greeting each person in a line — one by one, until the last."
  • "An accumulator is like a piggy bank: it starts at 0, and on each pass you put something in."
  • "A tuple is like a birth certificate — written once and never changed. A list is like a shopping list — it changes every day."

Type this code live (share screen)

Step 1 — loop_lists.py

python
matunda = ["embe", "ndizi", "chungwa"]
for tunda in matunda:
    print("Ninapenda", tunda)
text
Ninapenda embe
Ninapenda ndizi
Ninapenda chungwa

Step 2 — Accumulator: total and largest (without max)

python
bei = [1500, 3200, 800, 4500, 2000]
jumla = 0
kubwa = bei[0]
for b in bei:
    jumla += b
    if b > kubwa:
        kubwa = b
print("Jumla:", jumla)     # Jumla: 12000
print("Ghali zaidi:", kubwa)   # Ghali zaidi: 4500

Step 3 — Filter and transform

python
alama = [45, 82, 67, 30, 91, 58]

waliofaulu = []
for a in alama:
    if a >= 50:
        waliofaulu.append(a)
print(waliofaulu)              # [82, 67, 91, 58]

zilizoongezwa = []
for a in alama:
    zilizoongezwa.append(a + 5)
print(zilizoongezwa)           # [50, 87, 72, 35, 96, 63]

Then the shortcut (list comprehension):

python
waliofaulu = [a for a in alama if a >= 50]
zilizoongezwa = [a + 5 for a in alama]
print(waliofaulu, zilizoongezwa)

Step 4 — enumerate

python
wanafunzi = ["Amina", "Baraka", "Neema"]
for i, jina in enumerate(wanafunzi, start=1):
    print(f"{i}. {jina}")
text
1. Amina
2. Baraka
3. Neema

Another (older) way — understand it when you see it online:

python
for i in range(len(wanafunzi)):
    print(i, wanafunzi[i])

Step 5 — Building a list from input

python
namba = []
while True:
    x = input("Weka alama (au 'q' kumaliza): ")
    if x == "q":
        break
    namba.append(int(x))
print("Alama:", namba)
if namba:
    print("Wastani:", sum(namba) / len(namba))
else:
    print("Hakuna alama.")

Step 6 — Tuples

python
siku = ("Jumatatu", "Jumanne", "Jumatano", "Alhamisi", "Ijumaa")
print(siku[0], len(siku))       # Jumatatu 5
print(type(siku))               # <class 'tuple'>

dodoma = (-6.16, 35.75)         # (latitude, longitude)
lat, lon = dodoma               # unpacking
print(f"Latitude {lat}, Longitude {lon}")

a, b = 1, 2
a, b = b, a                     # kubadilishana
print(a, b)                     # 2 1

moja = (5,)
si_tuple = (5)
print(type(moja), type(si_tuple))   # <class 'tuple'> <class 'int'>

Show the error:

python
siku[0] = "Monday"
# TypeError: 'tuple' object does not support item assignment

Step 7 — A list of tuples (prepares for Session 3)

python
bidhaa = [("Sukari", 3000), ("Mchele", 2800), ("Mafuta", 6500)]
jumla = 0
for jina, bei in bidhaa:
    print(f"{jina:<10}{bei:>8,}")
    jumla += bei
print(f"{'JUMLA':<10}{jumla:>8,}")
text
Sukari       3,000
Mchele       2,800
Mafuta       6,500
JUMLA       12,300

Questions to ask the student

  1. How would we write a loop that prints only the even numbers from a list? — Answer: for n in l: if n % 2 == 0: print(n).
  2. Why is jumla = 0 outside the loop? — Answer: If it were inside, it would go back to 0 on every pass.
  3. The main difference between a list and a tuple? — Answer: A list can change (mutable) []; a tuple cannot change (immutable) ().
  4. x = (7) — what type is it? — Answer: int. A one-element tuple is (7,).
  5. What does enumerate give? — Answer: A pair of (index, element).

Common mistakes

Mistake Error message Fix
Changing a tuple TypeError: 'tuple' object does not support item assignment Use a list, or create a new tuple.
Mismatched unpacking ValueError: too many values to unpack (expected 2) The number of variables must match the number of elements.
for i in len(l): TypeError: 'int' object is not iterable for i in range(len(l)): or for x in l:
Removing inside a loop over the same list No error, but elements get skipped Create a new list with a filter.
Average of an empty list ZeroDivisionError: division by zero if l: before dividing.
Confusing the element name with the list for matunda in matunda: destroys the list Use a singular name: for tunda in matunda:

In-class exercise

  1. There is joto = [28, 31, 25, 33, 29, 35, 27] (temperatures for the week, in degrees). Print the days (numbers 1–7) with a temperature above 30, using enumerate.
  2. From majina = ["amina", "juma", "neema", "ali", "baraka"] (names), create a new list of names with more than 4 letters, with a capital first letter. Do it with a loop, then with a list comprehension.
  3. Create a list of tuples (jina, alama) (name, marks) for 4 students; print the name of the one with the highest marks.
Answer
python
# zoezi 1
joto = [28, 31, 25, 33, 29, 35, 27]
for siku, t in enumerate(joto, start=1):
    if t > 30:
        print(f"Siku {siku}: {t}°C")
# Siku 2: 31°C, Siku 4: 33°C, Siku 6: 35°C
python
# zoezi 2
majina = ["amina", "juma", "neema", "ali", "baraka"]
mpya = []
for j in majina:
    if len(j) > 4:
        mpya.append(j.title())
print(mpya)                    # ['Amina', 'Neema', 'Baraka']

mpya2 = [j.title() for j in majina if len(j) > 4]
print(mpya2)
python
# zoezi 3
matokeo = [("Amina", 78), ("Juma", 91), ("Neema", 85), ("Ali", 60)]
bora_jina, bora_alama = matokeo[0]
for jina, alama in matokeo:
    if alama > bora_alama:
        bora_jina, bora_alama = jina, alama
print(f"Bora: {bora_jina} ({bora_alama})")    # Bora: Juma (91)

Session 3 — Dictionaries, Sets, Nested Structures and Choosing the Right Structure

Session flow

  1. Homework review
  2. Dictionary: key/value, adding, changing, deleting, .get(), in
  3. Going through a dict: .keys(), .values(), .items(); counting words
  4. Break
  5. Sets: removing duplicates, operations
  6. Nested: a list of dicts (students), a dict of lists
  7. Choosing the right structure (table)
  8. Q&A + homework

Explanation for the teacher (read this first)

  • A dictionary (dict) stores key: value pairs inside {}: mwanafunzi = {"jina": "Amina", "umri": 20} (student: name, age). You get a value by its key, not an index: mwanafunzi["jina"].
  • Keys must be unique and unchangeable (str, int, tuple — not list). Values can be anything.
  • Operations:
    • Reading: d["key"] → KeyError if missing. d.get("key") → None if missing; d.get("key", 0) → 0 if missing.
    • Adding/changing: d["key"] = thamani (thamani = value; if the key exists it is changed, if not it is added).
    • Deleting: del d["key"] or d.pop("key").
    • Checking: "key" in d (checks keys, not values).
    • len(d) → the number of pairs.
  • Going through it: for k in d: (keys), for v in d.values():, for k, v in d.items():.
  • Since Python 3.7, a dict remembers insertion order.
  • Counting pattern: hesabu[neno] = hesabu.get(neno, 0) + 1 (hesabu = count, neno = word).
  • A set is a collection with no duplicates and no order: {1, 2, 3}. An empty set is set() — not {} (that is an empty dict!). It has no index. Uses: removing duplicates with set(l), checking membership quickly, and set mathematics: a | b (union), a & b (intersection), a - b (difference). Methods: add, remove, discard.
  • Nested: a list of dicts is a very common structure for "records" (like an Excel sheet: each dict is a row): wanafunzi = [{"jina": "Amina", "alama": 78}, ...]. Accessing: wanafunzi[0]["jina"].
  • Choosing a structure: | Need | Use | |---|---| | A sequence that changes, order matters, duplicates allowed | list | | Data that doesn't change (dates, coordinates) | tuple | | Looking up by name/key (phone by name, price by product) | dict | | Unique items, removing duplicates, comparing groups | set | | Many records with many fields | list of dict |

Say this to the student

  • "A dictionary is like the TUKI dictionary: you look up a word (key) and get its meaning (value). You don't look for 'word number 2,345' — you look for the word itself."
  • "Or like the phonebook on your phone: name → number."
  • "A set is like an attendance list — one name isn't written twice, even if a person comes in twice."
  • "A list of dicts is like an Excel sheet: each row is one student (dict), and the columns are 'jina' (name), 'alama' (marks), and so on."

Type this code live (share screen)

Step 1 — dicts.py

python
mwanafunzi = {
    "jina": "Amina",
    "umri": 20,
    "mji": "Dodoma",
}
print(mwanafunzi)             # {'jina': 'Amina', 'umri': 20, 'mji': 'Dodoma'}
print(mwanafunzi["jina"])     # Amina
print(len(mwanafunzi))        # 3

mwanafunzi["umri"] = 21               # kubadilisha
mwanafunzi["kozi"] = "Python"         # kuongeza
del mwanafunzi["mji"]                 # kufuta
print(mwanafunzi)             # {'jina': 'Amina', 'umri': 21, 'kozi': 'Python'}

print("jina" in mwanafunzi)           # True
print("Amina" in mwanafunzi)          # False (in inaangalia keys)
print(mwanafunzi.get("simu"))         # None
print(mwanafunzi.get("simu", "hakuna"))   # hakuna

Show the error:

python
print(mwanafunzi["simu"])
# KeyError: 'simu'

Step 2 — Going through a dict: shop prices

python
bei = {"sukari": 3000, "mchele": 2800, "mafuta": 6500, "chumvi": 500}

for bidhaa in bei:
    print(bidhaa)

for bidhaa, kiasi in bei.items():
    print(f"{bidhaa.title():<8} {kiasi:>6,} TZS")

print("Jumla ya bei zote:", sum(bei.values()))   # 12800
print("Bidhaa:", list(bei.keys()))

Step 3 — Example: a shop (dict + input)

python
bei = {"sukari": 3000, "mchele": 2800, "mafuta": 6500, "chumvi": 500}
jumla = 0
while True:
    bidhaa = input("Bidhaa (au 'mwisho'): ").strip().lower()
    if bidhaa == "mwisho":
        break
    if bidhaa not in bei:
        print("Hatuna bidhaa hiyo.")
        continue
    idadi = int(input("Idadi: "))
    jumla += bei[bidhaa] * idadi
print(f"Jumla ya kulipa: {jumla:,} TZS")

Step 4 — Counting pattern: counting words

python
sentensi = "haba na haba hujaza kibaba na haba"
hesabu = {}
for neno in sentensi.split():
    hesabu[neno] = hesabu.get(neno, 0) + 1
print(hesabu)
# {'haba': 3, 'na': 2, 'hujaza': 1, 'kibaba': 1}

Explain the inner line slowly: "hesabu.get(neno, 0) — if the word is already there, take its count; if not, take 0. Then add 1, and store it again."

Step 5 — Sets

python
mahudhurio = ["Amina", "Juma", "Amina", "Neema", "Juma", "Ali"]
wa_kipekee = set(mahudhurio)
print(wa_kipekee)          # {'Juma', 'Ali', 'Amina', 'Neema'} (mpangilio unaweza kutofautiana)
print(len(wa_kipekee))     # 4

python_darasa = {"Amina", "Juma", "Neema"}
hisabati_darasa = {"Juma", "Ali", "Neema", "Zawadi"}
print(python_darasa | hisabati_darasa)   # wote (union)
print(python_darasa & hisabati_darasa)   # walio madarasa yote mawili: {'Juma', 'Neema'}
print(python_darasa - hisabati_darasa)   # wa Python tu: {'Amina'}

python_darasa.add("Baraka")
python_darasa.discard("Mtu_asiyekuwepo")   # haileti error
print("Amina" in python_darasa)            # True

tupu = {}
print(type(tupu))          # <class 'dict'>  ← si set!
tupu_set = set()
print(type(tupu_set))      # <class 'set'>

Step 6 — Nested: a list of dicts

python
wanafunzi = [
    {"jina": "Amina", "alama": [78, 85, 90]},
    {"jina": "Juma", "alama": [65, 70, 58]},
    {"jina": "Neema", "alama": [92, 88, 95]},
]

print(wanafunzi[0]["jina"])        # Amina
print(wanafunzi[2]["alama"][1])    # 88

for m in wanafunzi:
    wastani = sum(m["alama"]) / len(m["alama"])
    print(f"{m['jina']:<8} wastani: {wastani:.1f}")

wanafunzi.append({"jina": "Ali", "alama": [50, 61, 47]})
print("Idadi ya wanafunzi:", len(wanafunzi))
text
Amina
88
Amina    wastani: 84.3
Juma     wastani: 64.3
Neema    wastani: 91.7
Idadi ya wanafunzi: 4

Notice: inside an f-string with "..." we used m['jina'] (single quotes) — this matters for Python 3.11 and below. Python 3.12+ even allows the same quotes, but this habit is safer.

Step 7 — A dict of lists

python
masomo = {
    "Jumatatu": ["Hisabati", "Python"],
    "Jumatano": ["Kiingereza"],
}
masomo["Jumatano"].append("Python")
masomo["Ijumaa"] = ["Fizikia", "Python"]
for siku, orodha in masomo.items():
    print(f"{siku}: {', '.join(orodha)}")
text
Jumatatu: Hisabati, Python
Jumatano: Kiingereza, Python
Ijumaa: Fizikia, Python

Questions to ask the student

  1. For a phonebook (name → number), which structure would you use? — Answer: dict.
  2. The difference between d["x"] and d.get("x") when the key is missing? — Answer: the first gives KeyError; the second gives None.
  3. Is {} a set or a dict? — Answer: an empty dict. An empty set is set().
  4. How would you remove duplicates from a list? — Answer: list(set(l)) (but the order may be lost).
  5. How do you access the first mark of the second student in wanafunzi? — Answer: wanafunzi[1]["alama"][0].
  6. For the days of the week (they don't change), what would you use? — Answer: tuple.
  7. Why can't a list be a dict key? — Answer: Because it can change (mutable/unhashable); use a tuple.

Common mistakes

Mistake Error message Fix
A key that doesn't exist KeyError: 'simu' .get() or if "simu" in d:
Using an index on a dict d[0] → KeyError: 0 A dict uses keys.
A list as a key TypeError: unhashable type: 'list' Use a tuple.
An index on a set TypeError: 'set' object is not subscriptable Convert to a list or use in.
{} when you want a set AttributeError: 'dict' object has no attribute 'add' set()
Forgetting a comma between pairs SyntaxError: invalid syntax. Perhaps you forgot a comma? Put a comma after each pair.
Quotes inside an f-string (Python ≤3.11) SyntaxError: f-string: unmatched '[' Use different quotes: f"{m['jina']}".
Changing a dict's size inside its loop RuntimeError: dictionary changed size during iteration Go through list(d.keys()) or create a new dict.

In-class exercise

  1. Create a phonebook (dict) of 3 people. Ask for a name; display the number or "Hayupo" (not there).
  2. Count the letters in the word "mississippi" with a dict (counting pattern).
  3. You have orodha_a = ["Amina", "Juma", "Ali"] and orodha_b = ["Ali", "Neema", "Juma"]. Display those on both lists, and everyone without duplicates.
  4. For the list of dicts wanafunzi (Step 6), print the name of the student with the highest average.
Answer
python
# zoezi 1
simu = {"Amina": "0712000111", "Juma": "0754222333", "Neema": "0688444555"}
jina = input("Jina: ").strip().title()
print(simu.get(jina, "Hayupo"))
python
# zoezi 2
hesabu = {}
for h in "mississippi":
    hesabu[h] = hesabu.get(h, 0) + 1
print(hesabu)     # {'m': 1, 'i': 4, 's': 4, 'p': 2}
python
# zoezi 3
a = set(["Amina", "Juma", "Ali"])
b = set(["Ali", "Neema", "Juma"])
print("Kwenye zote:", a & b)      # {'Juma', 'Ali'}
print("Wote:", a | b)             # {'Amina', 'Juma', 'Ali', 'Neema'}
python
# zoezi 4
wanafunzi = [
    {"jina": "Amina", "alama": [78, 85, 90]},
    {"jina": "Juma", "alama": [65, 70, 58]},
    {"jina": "Neema", "alama": [92, 88, 95]},
]
bora = None
bora_wastani = -1
for m in wanafunzi:
    w = sum(m["alama"]) / len(m["alama"])
    if w > bora_wastani:
        bora_wastani = w
        bora = m["jina"]
print(f"Bora: {bora} ({bora_wastani:.1f})")    # Bora: Neema (91.7)

Homework

HW1 (after Session 1, bring to Session 2): orodha_manunuzi.py (shopping list) — a program that lets the user add products to a list until they type "mwisho" (end), without repeating a product already there — use in. At the end display the sorted list and the number of products.

HW2 (after Session 2, bring to Session 3): takwimu.py (statistics) — ask for numbers separated by spaces (e.g. 4 8 15 16 23 42). Without using sum/max/min, with a loop, calculate the total, largest, smallest and average. Then create a list of the numbers above the average. Return the largest and smallest as a tuple (ndogo, kubwa) (smallest, largest) and print it.

HW3 (after Session 3, bring to the next session): kamusi.py (dictionary) — a small Swahili→English dictionary (5+ words). A menu in a while True: 1) Translate a word, 2) Add a new word, 3) Show all words (sorted), 4) Exit. Bonus: count how many words were searched for that aren't there (use a set to store those words without duplicates).

Answer
python
# orodha_manunuzi.py
orodha = []
while True:
    bidhaa = input("Bidhaa (au 'mwisho'): ").strip().lower()
    if bidhaa == "mwisho":
        break
    if bidhaa == "":
        continue
    if bidhaa in orodha:
        print(f"'{bidhaa}' tayari iko kwenye orodha.")
    else:
        orodha.append(bidhaa)
orodha.sort()
print("Orodha yako:")
for i, b in enumerate(orodha, start=1):
    print(f"{i}. {b}")
print("Idadi:", len(orodha))
python
# takwimu.py
vipande = input("Namba (tenganisha kwa nafasi): ").split()
namba = []
for v in vipande:
    namba.append(float(v))

jumla = 0
kubwa = namba[0]
ndogo = namba[0]
for n in namba:
    jumla += n
    if n > kubwa:
        kubwa = n
    if n < ndogo:
        ndogo = n
wastani = jumla / len(namba)
juu_ya_wastani = [n for n in namba if n > wastani]
mipaka = (ndogo, kubwa)

print("Jumla:", jumla)
print("Wastani:", round(wastani, 2))
print("Juu ya wastani:", juu_ya_wastani)
print("(ndogo, kubwa):", mipaka)
# 4 8 15 16 23 42 -> Jumla 108.0, Wastani 18.0, Juu: [23.0, 42.0], (4.0, 42.0)
python
# kamusi.py
kamusi = {
    "maji": "water",
    "chakula": "food",
    "nyumba": "house",
    "rafiki": "friend",
    "shule": "school",
}
hayapo = set()

while True:
    print("\n1) Tafsiri  2) Ongeza  3) Onyesha yote  4) Toka")
    chaguo = input("Chagua: ").strip()
    if chaguo == "1":
        neno = input("Neno la Kiswahili: ").strip().lower()
        if neno in kamusi:
            print(f"{neno} = {kamusi[neno]}")
        else:
            print("Neno hilo halipo.")
            hayapo.add(neno)
    elif chaguo == "2":
        sw = input("Kiswahili: ").strip().lower()
        en = input("Kiingereza: ").strip().lower()
        kamusi[sw] = en
        hayapo.discard(sw)
        print("Limeongezwa!")
    elif chaguo == "3":
        for sw in sorted(kamusi):
            print(f"{sw:<10} -> {kamusi[sw]}")
    elif chaguo == "4":
        print(f"Maneno {len(hayapo)} yalitafutwa bila kupatikana: {hayapo}")
        print("Kwaheri!")
        break
    else:
        print("Chaguo si sahihi.")

If you are asked a question you don't know

End-of-week checklist

  • Creates a list, uses index/slicing, and changes an element
  • Uses append, insert, extend, remove, pop, sort
  • Knows the difference between sort() and sorted() (and the l = l.sort() trap)
  • Understands b = a versus a.copy()
  • Writes the accumulate, filter and transform patterns with for
  • Uses enumerate and split/join
  • Knows a tuple is immutable, does unpacking, and knows (5,)
  • Uses a dict: reading, .get(), adding, deleting, .items()
  • Writes the counting pattern with a dict
  • Uses a set to remove duplicates and | & -; knows set() is not {}
  • Accesses data inside a list of dicts (l[0]["jina"])
  • Can explain when to use a list, tuple, dict or set