Ordered collections — how you hold multiple values together and work with them one at a time or all at once.
A list holds multiple values together, in order, inside square brackets, separated by commas.
groups = ["Engineering", "VPN-Users"]
print(groups)
Create a list fruits with "apple" and "banana", then print it.
fruits = ["apple", "banana"]
print(fruits)Create a list counts with 1, 2, 3, then print it.
counts = [1, 2, 3]
print(counts)Create an empty list called todo, then print it.
todo = []
print(todo) → []A list can mix types. Create mixed with "IT", 5, and True together, then print it.
mixed = ["IT", 5, True]
print(mixed)Create groups with two department names of your choice, then print it.
groups = ["Sales", "IT"]Open problems/01_create.py and do all 5 problems locally.
Printing a list shows its exact structure — brackets and quotes included. Printing a plain string doesn't show quotes; printing a list of strings does.
print("cat") # cat
print(["cat"]) # ['cat']
Print ["a", "b", "c"] directly.
['a', 'b', 'c']Print [1, 2, 3] — notice no quotes, since they're numbers.
[1, 2, 3]fruits = ["apple", "banana"]. Print fruits[0] alone, then print fruits whole — compare.
apple then ['apple', 'banana']Print an empty list.
[]Print [True, 5] — a boolean and a number together.
[True, 5]Open problems/02_print.py and do all 5 problems locally.
Each item in a list has a position, called an index, starting at 0 — not 1. list[0] gets the first item.
groups = ["Engineering", "VPN-Users"]
print(groups[0]) # Engineering
fruits = ["apple", "banana", "cherry"]. Print the first item.
applePrint the second item (index 1).
bananaPrint the third item (index 2).
cherryPredict: what does fruits[0] print?
applefruits only has 3 items (indexes 0, 1, 2). What happens with print(fruits[5])?
IndexError: list index out of rangeThere's no item at position 5 — Python tells you instead of guessing.
Open problems/03_index_positive.py and do all 6 problems locally.
Negative indexes count from the end. -1 is always the last item, -2 the second-to-last.
groups = ["Engineering", "VPN-Users"]
print(groups[-1]) # VPN-Users
fruits = ["apple", "banana", "cherry"]. Print the last item using a negative index.
cherryPrint the second-to-last item.
bananaPrint fruits[-3] — what does it land on?
apple (the first item, counting back 3 from the end)Compare: print fruits[0] then fruits[-3] — same list, same item.
applePredict: fruits[-1] vs fruits[2] on a 3-item list — same or different?
cherryPrint the last item of a 1-item list ["only"] using [-1].
onlyOpen problems/04_index_negative.py and do all 6 problems locally.
len() — the same function you used on strings — works on lists too. It counts the items.
groups = ["Engineering", "VPN-Users"]
print(len(groups)) # 2
Print len(["a", "b", "c"]).
3Print len([]) — an empty list.
0fruits = ["apple", "banana", "cherry"]. Print fruits[len(fruits) - 1] — the last item, the long way.
cherryCompare len(fruits) to len("fruits") (the word) — different things being counted.
3 then 6Print len([1, 2, 3, 4, 5]).
5One script: create a list, print it, print its first item, its last item (negative index), and its length. Four print statements.
Open problems/05_length.py — 6 problems, #6 is a checkpoint combining sub-skills 1–5.
in asks a yes/no question: is this value anywhere in the list? It answers with True or False — same idea as == and is from Module 1, just a different question.
groups = ["Engineering", "VPN-Users"]
print("Engineering" in groups) # True
print("Sales" in groups) # False
fruits = ["apple", "banana"]. Print "apple" in fruits.
TruePrint "cherry" in fruits.
FalsePrint "apple" not in fruits (the opposite check).
FalsePrint 5 in [1, 2, 3, 4, 5].
TruePrint "x" in [] — checking an empty list.
Falsegroups = ["Engineering", "VPN-Users"]. What does print(bool("Engineering" in groups)) print — is it different from just print("Engineering" in groups)?
Truein already gives back True/False directly, so wrapping it in bool() changes nothing.
Open problems/06_membership.py and do all 7 problems locally.
.append() adds one item to the end of a list, without erasing anything already there.
groups = ["Engineering"]
groups.append("VPN-Users")
print(groups) # ['Engineering', 'VPN-Users']
fruits = ["apple"]. Append "banana", print the result.
['apple', 'banana']Append "cherry" too (two appends in a row), print.
['apple', 'banana', 'cherry']Start with todo = []. Append "buy milk", print.
['buy milk']After appending, print the list's len() to confirm it grew.
2Append a number to a list of numbers: [1, 2], append 3, print.
[1, 2, 3]Append, then check membership: append "Sales" to groups, then print "Sales" in groups.
TrueAppend, then print the last item using [-1] to confirm it landed at the end.
Append three different values in a row to an empty list, print the final list and its length.
3Open problems/07_append.py and do all 8 problems locally.
.insert(position, value) puts a new item at a specific spot — everything after it shifts over by one.
groups = ["Engineering", "VPN-Users"]
groups.insert(0, "Admins")
print(groups) # ['Admins', 'Engineering', 'VPN-Users']
fruits = ["apple", "banana"]. Insert "cherry" at position 0, print.
['cherry', 'apple', 'banana']Insert "kiwi" at position 1, print.
Insert at position 0 into an empty list, print.
Compare: append "x" to one copy, insert "x" at position 0 into another copy — print both, notice the difference.
Insert, then check the list's len() grew by 1.
Insert, then confirm with in that the new value is now present.
TrueInsert at a position past the end, e.g. position 99 on a 2-item list — predict, then run.
Open problems/08_insert.py and do all 7 problems locally.
.remove(value) deletes the first item that matches the value you give it.
groups = ["Engineering", "VPN-Users"]
groups.remove("VPN-Users")
print(groups) # ['Engineering']
fruits = ["apple", "banana", "cherry"]. Remove "banana", print.
['apple', 'cherry']Remove the first item by value, print.
Remove, then check len() shrank by 1.
Remove, then confirm with in that the value is gone.
Falsefruits = ["apple", "banana"]. What happens with fruits.remove("cherry") — a value that isn't there?
ValueError: list.remove(x): x not in listSame pattern as int("N/A") from Module 1 — an operation that only works if the thing you're asking for actually exists.
Before removing, check "cherry" in fruits first — a safe way to avoid the crash above (don't fix the crash, just observe the check).
False, so you'd know not to remove itOpen problems/09_remove.py and do all 7 problems locally.
.pop() removes by position instead of value — and hands back what it removed, so you can use it. With no position given, it removes the last item.
groups = ["Engineering", "VPN-Users"]
removed = groups.pop()
print(removed) # VPN-Users
print(groups) # ['Engineering']
fruits = ["apple", "banana", "cherry"]. Pop the last item into a variable, print the variable.
cherryAfter popping, print fruits — confirm it shrank.
['apple', 'banana']Pop by position: fruits.pop(0) — removes and returns the first item instead.
applePop, then check len() shrank by 1.
Compare: .remove("apple") (by value) vs .pop(0) (by position) — same result on ["apple", "banana"], different reasoning.
['banana']Pop from a 1-item list, print what was popped and the now-empty list.
[]Predict: what happens if you .pop() an empty list?
IndexError: pop from empty listOne script: append two items, remove one by value, pop the other, print what was popped, and print the final (now empty) list.
Open problems/10_pop.py — 8 problems, #8 is a checkpoint combining sub-skills 6–10.
An empty list is falsy — same truthiness rule from Module 1. bool(my_list) tells you whether it has anything in it.
groups = []
print(bool(groups)) # False — empty
Print bool([]).
FalsePrint bool(["apple"]) — one item.
TrueStart with todo = ["task"], pop the only item, then print bool(todo).
FalseCompare len(my_list) == 0 to bool(my_list) on the same empty list — same answer, different route.
True and False respectively, both correctly identify "empty"Your fixture has 3 users with empty groups lists. Print bool([]) to confirm what that looks like.
FalseRemove the only item from a 1-item list by value, print bool() of the result.
FalseOpen problems/11_empty_check.py and do all 6 problems locally.
list[start:end] grabs a sub-range. The item at end is not included — it stops just before it.
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[0:2]) # ['apple', 'banana'] — stops before index 2
fruits = ["apple", "banana", "cherry", "date"]. Print fruits[0:2].
['apple', 'banana']Print fruits[1:3].
['banana', 'cherry']Print fruits[:2] — leaving off the start means "from the beginning".
['apple', 'banana']Print fruits[2:] — leaving off the end means "to the end".
['cherry', 'date']Print fruits[:] — both left off, the whole list.
fruits has 4 items. What does fruits[0:4] print — does it include the item at index 4?
['apple', 'banana', 'cherry', 'date']There's no index 4 on a 4-item list (last is 3), so the "stop before end" rule just means it goes to the actual end. No crash, unlike indexing past the end with a single [].
Print fruits[1:1] — start and end the same.
[] — empty, nothing between position 1 and itselfSlice, then check the result's len().
Slice the first 2 items of a 5-item list of numbers, print the result.
Open problems/12_slicing.py and do all 8 problems locally.
+ joins two lists into a new one — same symbol you used to combine strings in Module 1.
a = ["Engineering"]
b = ["VPN-Users"]
print(a + b) # ['Engineering', 'VPN-Users']
a = ["apple"], b = ["banana"]. Print a + b.
['apple', 'banana']Combine, then print the combined list's len().
2Combine an empty list with a non-empty one, print the result.
Build one list via .append(), another as a literal, combine them with +, print.
Combine two lists, then check membership (in) of an item from the second list in the combined result.
TrueCombine, then slice the first 2 items of the result.
Combine two lists, then pop the last item off the combined result.
Combine two 2-item lists, print the result and confirm its length is 4.
Open problems/13_combine.py and do all 8 problems locally.
.count(value) tells you how many times a value appears in a list.
groups = ["VPN-Users", "Engineering", "VPN-Users"]
print(groups.count("VPN-Users")) # 2
letters = ["a", "b", "a", "c", "a"]. Print letters.count("a").
3Print letters.count("z") — a value not present.
0 (no crash, unlike .remove() on a missing value)Print letters.count("b").
1Count on an empty list.
0Append a duplicate value, then count it again — confirm it went up by 1.
Compare .count("a") > 0 to "a" in letters — same yes/no answer, different tool.
TrueCombine two lists that share a repeated value, then count it in the combined result.
Open problems/14_count.py and do all 7 problems locally.
.join() is backwards from the others — it's a string method, called on the separator, with the list passed in.
groups = ["Engineering", "VPN-Users"]
print(", ".join(groups)) # Engineering, VPN-Users
fruits = ["apple", "banana"]. Print ", ".join(fruits).
apple, bananaJoin with a dash instead: "-".join(fruits).
apple-bananaJoin with no separator: "".join(fruits).
applebananaJoin an empty list.
"" (empty string)Join a 1-item list — no separator shows up with only one item.
nums = [1, 2, 3]. What happens with ", ".join(nums)?
TypeError: sequence item 0: expected str instance, int found.join() only works on a list of strings — same family of bug as gluing text onto None back in Module 1. Numbers need str() first (a Module 1 tool).
Build a list via .append(), combine it with another list using +, then .join() the result into one comma-separated line.
Join a list built from a slice: take fruits[0:2], join it with ", ".
Join a filtered-by-hand list: manually write a list containing only the fruits you'd keep, join it.
Print a full one-line report: create a list of 3 items, append a 4th, and .join() them into one printed sentence.
One script using every sub-skill 1–15 at least once: create, print, index (both directions), length, membership, append, insert, remove, pop, empty-check, slice, combine, count, and join — ending in one printed summary line.
Open problems/15_join.py — 10 problems, #10 is the final checkpoint for all of Module 2.
Run python check.py in problems/ to grade everything.