COMP1701-004
fall 2023
lec-17
The Blue Block Continues Its Inexorable Advance





Marc Schroeder is present in class today and is conducting observations as part of an approved research study. No audio or video recording is being conducted.
His fieldnotes may record general observations about the overall nature of classroom activities and discussions. However, these will not include personal or identifying details about individuals or their participation, except for those students who are participating in other aspects of the study.
If you have any questions or concerns, then please let me know, and I’ll direct you to the appropriate resource.
any questions about A4?
DO THIS THING
Create a function that takes in a string and returns a list of all the "short" words in that string. Consider any word with 3 letters or less "short". Choose a good name, and don't forget those type hints!
# for example
shorties = yerfunction("my dog has numerous busy fleas")
# shorties should be ["my", "dog", "has"]
REVIEW
let's talk about these things today:
⦾ modifying existing list elements
⦾ adding/removing list elements
⦾ nested / 2D lists
⦾ iterating through 2D lists
⦾ a super-important list gotcha
modding existing list elements
lists : modding existing items
s = "string"
s[1] = "p"
print(s)Remember this from lec-15?
Strings are immutable, which is fancytalk for unchangeable.
💥
NO TOUCHY
lists : modding existing items
a_list = "My dog has fleas".split()
print(a_list) # ['My', 'dog', 'has', 'fleas']
a_list[3] = "rutabagas"
print(a_list) # ['My', 'dog', 'has', 'rutabagas']Lists don't have that issue!
Lists are mutable, which is fancytalk for changeable.
Let's practice mutating a list.
(It sounds way cooler than "changing".)
sound_measurements = [32, 40, 31, 58, 111]
num_measurements = len(sound_measurements)
i = 3
while (i > 1):
sound_measurements[i] = sound_measurements[i + 1]
i -= 1
for measurement in sound_measurements:
print(measurement, "", end="")🙋🏻♂️❓🙋🏻♀️What's sound_measurements[4]?
🙋🏻♂️❓🙋🏻♀️At what index can we find 40?
🙋🏻♂️❓🙋🏻♀️What is len(sound_measurements)?

🙋🏻♂️❓🙋🏻♀️
What does the above code print to the terminal?
Use Python Tutor after to reinforce.
We've now shown how to create a new list with items in it...
...and how to change existing items in a list...
...but how can we add and remove items themselves?
nummy_foods = ["pizza", "sushi", "nachos", "mac & cheese", "natto"]nummy_foods[len(nummy_foods) - 1] = "som tum"🙋🏻♂️❓🙋🏻♀️What's in our nummy_foods list now?
adding list elements
lists : adding/removing items
We can use the append method to add things to the end of a list
great_calgary_restaurants = [ ]
great_calgary_restaurants.append("River Café")
# Gimme some other great Calgary restaurants
# we'll use append to add them to the list to
# practice...and because I'm always on the
# lookout for good restaurants!REPL Time
lists : adding/removing items
We can use the + operator to add a list to the end of a list
drinks = ["OJ", "milk", "water"]
drinks = drinks + ["pop", "age-appropriate bev"]
print(drinks)
# ['OJ', 'milk', 'water', 'pop', 'age-appropriate bev']drinks = ["OJ", "milk", "water"]
drinks = drinks + "pseudowine" # Boomsville
print(drinks)Careful!
lists : adding/removing items
We can use the insert method to say "go to this index and add this item"
| "March Hare" | "Dormouse" | "Mad Hatter" |
|---|
| 0 | 1 | 2 |
|---|
tea_party = ["March Hare", "Dormouse", "Mad Hatter"]tea_party.insert(1, "Alice")| "March Hare" | "Alice" | "Dormouse" | "Mad Hatter" |
|---|
| 0 | 1 | 2 | 3 |
|---|
Alice butts in at index 1...
...and shoves everyone down
lists : adding/removing items
PREDICT
# Let's Python Tutor this one
# predict what the list will look like at each step
a = "True"
b = "True"
c = "False"
the_list = [a, b, c]
the_list.append(str(False))
the_list = the_list + ["Dunno"] + the_list
the_list.insert(0, c)
🙋🏻♂️❓🙋🏻♀️What's len(the_list[3])?
removing list elements
lists : adding/removing items
We can use the remove method to remove a specified thing from a list
| 39 | 12 | 31 | 12 | 92 |
|---|
| 0 | 1 | 2 | 3 | 4 |
|---|
house_nums.remove(12)The first 12 is removed...
...and everyone "slides over" into the "gap"
| 39 | 31 | 12 | 92 |
|---|
| 0 | 1 | 2 | 3 |
|---|
QUESTION
What do you think would happen if you tried to remove something that wasn't there?
house_nums = [39, 12, 31, 12, 92]lists : adding/removing items
We can use the del keyword to remove a thing at a specific index from a list
| "TS" | "AL" | "NR" | "DJ" |
|---|
| 0 | 1 | 2 | 3 |
|---|
initials = ["TS", "AL", "NR", "DJ"]del initials[0]| "AL" | "NR" | "DJ" |
|---|
| 0 | 1 | 2 |
|---|
watch that syntax - it's weird!
The specified item is removed...
...and everyone moves over into the "gap"
🙋🏻♂️❓🙋🏻♀️
What do you think would happen if you tried to remove something at an invalid index?
lists : adding/removing items
PREDICT
# Let's use the debugger on this one.
# Predict what the list will look like at each step.
a = True
b = True
c = False
the_list = [a, b, c]
the_list.append(False)
the_list.insert(0, c)
the_list.remove(b)
the_list += [True, True]
del the_list[3]
the_listlists : adding/removing items
There are many more useful list methods out there.
A good developer gets into the habit of browsing the docs for useful methods.
The Python Reference (The Right Way) does a nice job.


lists : lists of lists
Remember this?
| 112 | -4 | 9 |
|---|
| 0 | 1 | 2 |
|---|
list of ints
| 0.2 | 1.0 | -100.03 | -4.81 |
|---|
| 0 | 1 | 2 | 3 |
|---|
list of floats
| True | True | False | True | False |
|---|
| 0 | 1 | 2 | 3 | 4 |
|---|
list of bools
| "foo" | "hi there" |
|---|
| 0 | 1 |
|---|
list of strings
(ominous music plays)
| ["chicken", "beef"] | ["mashed potato", "baked potato"] | ["corn", "peas", "carrots"] |
|---|
| 0 | 1 | 2 |
|---|
list of lists aka 2D list
If a list can hold anything...
...then couldn't it hold other lists?!?

lists : modding existing items
movies = [
["Mad Max: Fury Road", "The Avengers", "Baby Driver"],
["Hellraiser", "The Mist", "Oculus"],
["2001", "Aliens", "Silent Running"],
["Caddyshack", "Airplane!", "The Big Lebowski"]
]
🙋🏻♂️❓🙋🏻♀️
What statement would mutate the list so that Caddyshack became Groundhog Day?
🙋🏻♂️❓🙋🏻♀️
What code would turn the list with Hellraiser in it into an empty list?
Let's practice mutating a 2D list.
movies_as_text = "Mad Max: Fury Road,The Avengers,Baby Driver"
movies_in_genres = [
movies_as_text.split(","),
["The Omen", "The Exorcist", "The Changeling"]
]
print(movies_in_genres[0])
print(movies_in_genres[1][0])
for movies in movies_in_genres:
print(movies[1])

Give This a Try
What is printed to the console by this code?
iterating through 2D/nested lists
lists : nested fors
Many problems you deal with in the Land of Software involves data in some sort of tabular format
skinny;10;42;32 lady bug;90;11;15 rickNmorty;48;22;98 D00MZDAY;99;101;12
video game high scores
2 0 2 -5 -3 -2 -5 -5 -5 -2 -11 -4 -8 -4 -6 -14 -6 -8 -12 -4 -3 -3 -13 -15 -6 2 -14 -7 1 -10 0 9 4 -3 5 8 -3 2 0 7
temp ranges over 4 days
First Tube, 8:41 Gotta' Jibboo, 11:54 Foam, 9:09 The Lizards, 10:18 You Enjoy Myself, 20:57
live Phish song durations
G4|--|R2 G3|--|S2 W2|--|W1
dice arrangements
lists : nested fors
Such data can often nicely be represented using lists of lists
skinny;10;42;32 lady bug;90;11;15 rickNmorty;48;22;98 D00MZDAY;99;101;12
video game high scores
2 0 2 -5 -3 -2 -5 -5 -5 -2 -11 -4 -8 -4 -6 -14 -6 -8 -12 -4 -3 -3 -13 -15 -6 2 -14 -7 1 -10 0 9 4 -3 5 8 -3 2 0 7
temp ranges over 4 days
First Tube, 8:41 Gotta' Jibboo, 11:54 Foam, 9:09 The Lizards, 10:18 You Enjoy Myself, 20:57
live Phish song durations
G4|--|R2 G3|--|S2 W2|--|W1
dice arrangements
high_scores = [
["skinny", [10, 42, 32]],
["lady bug", [90, 11, 15]],
["rickNmorty", [48, 22, 98]],
["D00MZDAY", [99, 101, 12]]
]temp_ranges = [
[2, 0, 2, -5, -3, -2, -5, -5, -5, -2],
[-11, -4, -8, -4, -6, -14, -6, -8, -12, -4],
[-3, -3, -13, -15, -6, 2, -14, -7, 1, -10],
[0, 9, 4, -3, 5, 8, -3, 2, 0, 7]
]
song_durations = [
["First Tube", [8, 41]],
["Gotta' Jibboo", [11, 54]],
["Foam", [9, 9]],
["The Lizards", [10, 18]],
["You Enjoy Myself", [20, 57]],
]building = [
["G4", '', "R2"],
["G3", '', "S2"],
["W2", '', "W1"],
]
You don't have to follow the original data format - you can make choices that make your life easier!
QUESTION
How do you suppose you could create these lists if the original data was text?
lists : nested fors
We usually want to walk - or iterate - through all "inner" lists inside the "outer" list and do something
high_scores = [
["skinny", [10, 42, 32]],
["lady bug", [90, 11, 15]],
["rickNmorty", [48, 22, 98]],
["D00MZDAY", [99, 101, 12]]
]temp_ranges = [
[2, 0, 2, -5, -3, -2, -5, -5, -5, -2],
[-11, -4, -8, -4, -6, -14, -6, -8, -12, -4],
[-3, -3, -13, -15, -6, 2, -14, -7, 1, -10],
[0, 9, 4, -3, 5, 8, -3, 2, 0, 7]
]
song_durations = [
["First Tube", [8, 41]],
["Gotta' Jibboo", [11, 54]],
["Foam", [9, 9]],
["The Lizards", [10, 18]],
["You Enjoy Myself", [20, 57]],
]building = [
["G4", '', "R2"],
["G3", '', "S2"],
["W2", '', "W1"],
]
print the number of high scores under 40 for each player
find the average temperature across all days
find the glass score
find the shortest song longer than 10 minutes
lists : nested fors
This iteration is very often done using a nested for loop
high_scores = [
["skinny", [10, 42, 32]],
["lady bug", [90, 11, 15]],
["rickNmorty", [48, 22, 98]],
["D00MZDAY", [99, 101, 12]]
]print the number of high scores under 40 for each player
pseudocode
for every player in the outer list
["skinny", [10, 42, 32]],count the scores < 40 and print
need to loop through these scores and count
need to loop through each player's info
lists : nested fors
high_scores = [
["skinny", [10, 42, 32]],
["lady bug", [90, 11, 15]],
["rickNmorty", [48, 22, 98]],
["D00MZDAY", [99, 101, 12]]
]for curr_player in high_scores:
curr_player_name = curr_player[0]
curr_player_scores = curr_player[1]
under_40_count = 0
for curr_score in curr_player_scores:
if curr_score < 40:
under_40_count += 1
print(curr_player_name, ":", under_40_count)
skinny : 2 lady bug : 2 rickNmorty : 1 D00MZDAY : 1
A Solution
nesting hurts the brain...what could we do to lessen the ouch?
lists : nested fors
high_scores = [
["skinny", [10, 42, 32]],
["lady bug", [90, 11, 15]],
["rickNmorty", [48, 22, 98]],
["D00MZDAY", [99, 101, 12]]
]def num_scores_under_40(scores: list) -> int:
under_40_count = 0
for curr_score in scores:
if curr_score < 40:
under_40_count += 1
return under_40_count
for curr_player in high_scores:
curr_player_name = curr_player[0]
curr_player_scores = curr_player[1]
under_40_count = num_scores_under_40(curr_player_scores)
print(curr_player_name, ":", under_40_count)Functions make things less hurty
It's a bit less painful - and you can test the function separately, which is a plus.
a big list gotcha
a big list gotcha
x = "foo"
y = x
print("1: x is", x)
print("2: y is", y)
x += "bar"
print("3: x is", x)
print("4: y is", y)Predict what is printed
a big list gotcha
x = ["it's", "a", "monorail"]
y = x
print("1: x is", x)
print("2: y is", y)
del x[2]
x.append("trap!")
print("3: x is", x)
print("4: y is", y)Predict what is printed
WHAT DARK WITCHERY IS THIS?!?!
a big list gotcha
x = ["it's", "a", "monorail"]
y = x
print("1: x is", x)
print("2: y is", y)
del x[2]
x.append("trap!")
print("3: x is", x)
print("4: y is", y)Let's use Python Tutor
a big list gotcha
x = ["it's", "a", "monorail"]
loc_of_xs_list = id(x)
y = x
loc_of_ys_list = id(y)
print(f"1: the list x refers to is at {loc_of_xs_list}")
print(f"2: the list y refers to is at {loc_of_ys_list}")
del x[2]
x.append("trap!")
print("3: x is", x)
print("4: y is", y)
id() is a useful function to figure out "who" an object is
lec-17
By Jordan Pratt
lec-17
nested for | modifying lists | list return values | a list gotcha
- 195