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,aandbpoint 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...)
- Create a list, access elements by index and slicing, and change it.
- Use list methods:
append,insert,extend,remove,pop,sort,reverse,index,count, as well aslen,sum,min,max,sorted,in. - Go through a list with
for(includingenumerate), and build a new list inside a loop. - Use a tuple and understand why it cannot change; tuple unpacking.
- Use a dictionary: adding, changing, deleting,
.get(),.keys(),.values(),.items(), looping through it, counting. - Use a set: removing duplicates,
union,intersection,difference. - 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
- Homework review (FizzBuzz, PIN)
- Why do we need lists? Creating a list,
len, index - Slicing and changing an element
- Methods for adding and removing
- Break
sort,sorted,sum,min,max,in,index,count- Mutability:
b = aversusb = a.copy() - In-class exercise
- 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 endinsert(i, x)— add at indexiextend(list2)— add all the elements of another listremove(x)— remove the firstxfound (error if it isn't there)pop()— remove and return the last item;pop(i)— the item at indexisort()— sort (numbers: small→large; strings: alphabetical);sort(reverse=True)reverse()— reverse the orderclear()— 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()→ nowmatundaisNone! Becausesort()changes the list and returnsNone. Writematunda.sort()on its own, ormpya = sorted(matunda). - Mutability/aliasing:
b = adoesn't make a copy; it is a second label on the same list. To make a copy:b = a.copy()orb = 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 = ais 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
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
matunda[0] = "papai" print(matunda) # ['papai', 'ndizi', 'chungwa', 'nanasi']
Step 3 — Adding
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
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
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:
x = [3, 1, 2] x = x.sort() print(x) # None ← tatizo!
Step 6 — Mutability (the REPL is best here)
>>> 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
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
l = [10, 20, 30];l[1]? — Answer: 20.- The difference between
appendandextend? — Answer:l.append([1,2])adds the whole list as a single element;l.extend([1,2])adds 1 and 2 separately. - The difference between
sort()andsorted()? — Answer:sort()changes the list itself and returnsNone;sorted()returns a new list. pop()andremove()? — Answer:popremoves by index (and returns the item);removeremoves by value.- After
b = a; b.append(9), hasachanged? — 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
- Create a list of 5 Tanzanian towns. Add one at the end and one at the beginning, remove the third, sort alphabetically and print.
- There is a list
alama = [55, 78, 91, 34, 66, 78](marks). Print: the count, total, average, highest, lowest, and the top 3 marks. - Ask the user for comma-separated names; display the number of names and the names in sorted order.
Answer
# 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']
# 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]
# 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
- Homework review
forover a list; accumulator (total, largest)- Building a new list in a loop (filter);
enumerate;range(len()) - List comprehension (a short introduction)
- Break
- Tuples: creating, immutable, unpacking
- Lists inside lists (nested lists, a little)
- In-class exercise
- Q&A + homework
Explanation for the teacher (read this first)
for kitu in list:—kitu(item) takes each element in turn. You choose the namekituyourself (e.g.for tunda in matunda:— a singular name for a plural list is a good habit;tunda= fruit,matunda= fruits).- 3 important patterns:
- Accumulate:
jumla = 0→for x in l: jumla += x - Filter:
mpya = []→for x in l: if sharti: mpya.append(x) - Transform:
mpya = []→for x in l: mpya.append(x * 2)
- Accumulate:
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
removeinside aforover 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
countandindex. - Advantages: safe (it can't change by accident), and it can be a dict key (Session 3).
- A tuple with one element needs a comma:
Say this to the student
- "
forover 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
matunda = ["embe", "ndizi", "chungwa"] for tunda in matunda: print("Ninapenda", tunda)
Ninapenda embe Ninapenda ndizi Ninapenda chungwa
Step 2 — Accumulator: total and largest (without max)
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
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):
waliofaulu = [a for a in alama if a >= 50] zilizoongezwa = [a + 5 for a in alama] print(waliofaulu, zilizoongezwa)
Step 4 — enumerate
wanafunzi = ["Amina", "Baraka", "Neema"] for i, jina in enumerate(wanafunzi, start=1): print(f"{i}. {jina}")
1. Amina 2. Baraka 3. Neema
Another (older) way — understand it when you see it online:
for i in range(len(wanafunzi)): print(i, wanafunzi[i])
Step 5 — Building a list from input
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
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:
siku[0] = "Monday" # TypeError: 'tuple' object does not support item assignment
Step 7 — A list of tuples (prepares for Session 3)
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,}")
Sukari 3,000 Mchele 2,800 Mafuta 6,500 JUMLA 12,300
Questions to ask the student
- 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). - Why is
jumla = 0outside the loop? — Answer: If it were inside, it would go back to 0 on every pass. - The main difference between a list and a tuple? — Answer: A list can change (mutable)
[]; a tuple cannot change (immutable)(). x = (7)— what type is it? — Answer:int. A one-element tuple is(7,).- What does
enumerategive? — 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
- 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, usingenumerate. - 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. - Create a list of tuples
(jina, alama)(name, marks) for 4 students; print the name of the one with the highest marks.
Answer
# 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
# 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)
# 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
- Homework review
- Dictionary: key/value, adding, changing, deleting,
.get(),in - Going through a dict:
.keys(),.values(),.items(); counting words - Break
- Sets: removing duplicates, operations
- Nested: a list of dicts (students), a dict of lists
- Choosing the right structure (table)
- 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"]→KeyErrorif missing.d.get("key")→Noneif 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"]ord.pop("key"). - Checking:
"key" in d(checks keys, not values). len(d)→ the number of pairs.
- Reading:
- 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 isset()— not{}(that is an empty dict!). It has no index. Uses: removing duplicates withset(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 |listofdict|
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
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:
print(mwanafunzi["simu"]) # KeyError: 'simu'
Step 2 — Going through a dict: shop prices
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)
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
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
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
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))
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
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)}")
Jumatatu: Hisabati, Python Jumatano: Kiingereza, Python Ijumaa: Fizikia, Python
Questions to ask the student
- For a phonebook (name → number), which structure would you use? — Answer: dict.
- The difference between
d["x"]andd.get("x")when the key is missing? — Answer: the first givesKeyError; the second givesNone. - Is
{}a set or a dict? — Answer: an empty dict. An empty set isset(). - How would you remove duplicates from a list? — Answer:
list(set(l))(but the order may be lost). - How do you access the first mark of the second student in
wanafunzi? — Answer:wanafunzi[1]["alama"][0]. - For the days of the week (they don't change), what would you use? — Answer: tuple.
- 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
- Create a phonebook (dict) of 3 people. Ask for a name; display the number or "Hayupo" (not there).
- Count the letters in the word "mississippi" with a dict (counting pattern).
- You have
orodha_a = ["Amina", "Juma", "Ali"]andorodha_b = ["Ali", "Neema", "Juma"]. Display those on both lists, and everyone without duplicates. - For the list of dicts
wanafunzi(Step 6), print the name of the student with the highest average.
Answer
# zoezi 1 simu = {"Amina": "0712000111", "Juma": "0754222333", "Neema": "0688444555"} jina = input("Jina: ").strip().title() print(simu.get(jina, "Hayupo"))
# zoezi 2 hesabu = {} for h in "mississippi": hesabu[h] = hesabu.get(h, 0) + 1 print(hesabu) # {'m': 1, 'i': 4, 's': 4, 'p': 2}
# 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'}
# 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
# 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))
# 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)
# 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
- In the REPL type
help(list)ordir(dict)to see all the methods — that is the official way of "asking Python itself". Alsohelp(list.insert). - Search: "python list vs tuple", "python dictionary get default", "python set operations".
- Docs: https://docs.python.org/3/tutorial/datastructures.html , https://docs.python.org/3/library/stdtypes.html#mapping-types-dict , https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset
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()andsorted()(and thel = l.sort()trap) - Understands
b = aversusa.copy() - Writes the accumulate, filter and transform patterns with
for - Uses
enumerateandsplit/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
| & -; knowsset()is not{} - Accesses data inside a list of dicts (
l[0]["jina"]) - Can explain when to use a list, tuple, dict or set