0% found this document useful (0 votes)
2 views39 pages

Module 4 Slides

Module 4 covers the concepts of strings and lists as iterables in Python, including their indexing, length, and iteration using loops. It introduces exercises for practicing these concepts, such as extracting values from lists and strings, and designing algorithms for finding items in collections. The module emphasizes the importance of understanding algorithms and provides examples of how to implement them in code.

Uploaded by

Assam Shiraz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views39 pages

Module 4 Slides

Module 4 covers the concepts of strings and lists as iterables in Python, including their indexing, length, and iteration using loops. It introduces exercises for practicing these concepts, such as extracting values from lists and strings, and designing algorithms for finding items in collections. The module emphasizes the importance of understanding algorithms and provides examples of how to implement them in code.

Uploaded by

Assam Shiraz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Module 4: Strings and lists are

iterables
Exercise

If you have not already, get prepared for class by downloading the start code:
!wget [Link]

Discuss the previous module with your neighbour.

How do we write code to do something repeatedly?


How do we create functions that take a function as an argument?

1/41 CS 114 - Fall 2023 Module 4


Sequences

In mathematics, a sequence is a collection of items, in some order. Some examples:

The natural numbers: 0, 1, 2, 3, 4, . . .


The prime numbers: 2, 3, 5, 7, 11, 13, 17, 19, 23 . . .
The Collatz sequence starting at 3 and ending at 1: 3, 10, 5, 16, 8, 4, 2, 1

In mathematics sequences are often infinitely long, but not always.


In programming we often work with sequences of finite length like [2, 4, 6, 0, 1].

2/41 CS 114 - Fall 2023 Module 4


Two kinds of iterables: strings and lists

A string such as "foobar" is a collection of characters, in some order:


the first item is 'f', the second is 'o', the third is another 'o', and so on.
"foobar" is like a sequence of letters.

Another way to have a collection of values is to make a list. In Python, we do this by


writing the values, separated by commas, inside square brackets [].
For example, [2, 4, 6, 0, 1] is a list that contains five integers:
the first item is 2, the second is 4, the third is 6, and so on.
[2, 4, 6, 0, 1] is like a sequence of integers.

3/41 CS 114 - Fall 2023 Module 4, Section 1: Strings and lists


Indexing

We can extract a single item from either of these iterables using indexing.
After a value we write square brackets around an integer called an index.
word = "foobar" jvj = [2, 4, 6, 0, 1]
word[0] ⇒ "f" jvj[0] ⇒ 2
word[1] ⇒ "o" jvj[1] ⇒ 4
word[2] ⇒ "o" jvj[2] ⇒ 6
word[3] ⇒ "b" jvj[3] ⇒ 0
word[4] ⇒ "a" jvj[4] ⇒ 1
word[5] ⇒ "r"

Notice: the first value is item 0, not item 1.


!
The last item is numbered 1 less than the length.

4/41 CS 114 - Fall 2023 Module 4, Section 1: Strings and lists


Indexing

rhg = ["Everything", "is", "theoretically", "impossible,", "until", "it", "is", "done."]

What is rhg[2] ?
rhg[2] ⇒ "theoretically"

But notice: rhg[2] is a str, and we can also index a str.


rhg[2][0] ⇒ "t"
Ex.

What is rhg[3][0] ? rhg[0][3] ?


Ex.

How many different ways can you use indexing on rhg to get "y" ?

Evaluation Principle: if an expression evaluates to something that we could use in


a certain way, we can use the expression in that way.

5/41 CS 114 - Fall 2023 Module 4, Section 1: Strings and lists


Indexing

Evaluation Principle: if an expression evaluates to something that we could use in


a certain way, we can use the expression in that way.
Exercise

mannie = [[12, 13, 14], [15, 16, 17], [18, 19, 20]]
Use indexing on mannie to get 17.
Exercise

wyoh = [["The", "five"], ["boxing", "wizards"], ["jump", "quickly"]]


Use indexing on wyoh to get "x".
Use indexing on wyoh to get "w".

6/41 CS 114 - Fall 2023 Module 4, Section 1: Strings and lists


Annotating lists

To describe a list, we say list, then inside square brackets, a single expression indicating
the type of the values that are in the list. Some examples:

[2, 4, 6, 0, 1] is a list[int], since each value is an int.


[3.14, 2.718, 1.414, 2.0] is a list[float], since each value is a float.
["we're", "all", "fine", "here", "now"] is a list[str], since each value is a str.

We could have a list that contains a mix of a few types, like [1, "word", 4, "you"], which
contains some int and some str. We’re going to avoid this; it’s usually a bad idea.
If we want to talk about a list where the values could be of any type, we can say list[any].

8/41 CS 114 - Fall 2023 Module 4, Section 1: Strings and lists


Length and walking using while

We can use the built-in function len to determine how many values an iterable contains:
len("foobar") ⇒ 6 len([2, 4, 6, 0, 1]) ⇒ 5

A while loop using len and a variable index can extract items one at a time:
i = 0 j = 0
word = "foobar" jvj = [2, 4, 6, 0, 1]
while i < len(word): while j < len(jvj):
print(i, word[i]) print(j, jvj[j])
i = i + 1 j = j + 1
## We see: ## We see:
0 f 0 2
1 o 1 4
2 o 2 6
3 b 3 0
4 a 4 1
5 r
Using a for loop

We often want to want to walk through an iterable.


Often we just need the values, not the counter.
To make it easier, Python provides the for loop.
It steps through the sequence, one item at a time, and sets a variable to each item.
word = "foobar" jvj = [2, 4, 6, 0, 1]
for letter in word: for number in jvj:
print(letter) print(number)
## We see: ## We see:
f 2
o 4
o 6
b 0
a 1
r

The first time through the loop, the variable takes the first value in the iterable; the second
time through, it takes the second value, and so on.
Syntax of for loops

word = "foobar" jvj = [2, 4, 6, 0, 1]


for letter in word: for number in jvj:
print(letter) print(number)

The syntax of for has some similarities to the syntax of if and while, and some new parts.
We write:
1 the keyword for,
2 the name of a variable,
3 the keyword in,
4 a sequence,
5 a colon,
6 an indented block of code.

The block of code will run repeatedly, with the taking a value from the sequence each time.
11/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for
Example: using for with if

We can use our tools together. Consider: Then drop_e("djent") will print:
def drop_e(word: str) -> None: d
"""Print all the letters in word except e.""" j
for letter in word:
n
if letter != 'e':
print(letter) t

Write a function count_e(word: str) -> int, that counts how many times 'e' appears
Exercise

in word. For example,


[Link]("CE1", count_e("hello"), 1)
[Link]("CE2", count_e("able was I ere I saw Elba"), 3)

Write a function count_n(target: float, vals: list[float]) -> int, that counts how
Exercise

many times target appears in vals. For example,


[Link]("Cn1", count_n(3.1, [2.5, 6.5, 3.1, 1.0]), 1)
[Link]("Cn2", count_n(2.1, [2.5, 2.1, 3.1, 2.1, 1.0, 2.1]), 3)

12/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Checking if an iterable contains a value

It’s common to want to check if some value is contained, somewhere, inside a str or list.
For example, does [2,4,6,0,1] contain the number 6? By looping through the list, one item
at a time, we eventually find the target; so the list does contain a 6, and we can return
True. We don’t even need to look at the 0 and 1.

Does [2,4,6,0,1] contain the number 7? Again, we loop through, and reach the end of the
loop, without ever finding the target. So it does not contain it; we can return False.

Use a for loop to write a function


Exercise

contains(target: int, collection: list[int]) -> bool. The function shall return True if
target appears in collection at least once.
[Link]("C6", contains(6, [2,4,6,0,1]), True)
[Link]("C7", contains(7, [2,4,6,0,1]), False)

Something neat: the same code works for a str:


[Link]("Cy", contains("y", "too many geese"), True)
[Link]("Cx", contains("x", "too many geese"), False)
The built-in operator in does the same thing

In the previous exercise you wrote code like this.


def contains(target: int, collection: list[int]) -> bool:
"""Return True if collection contains target, and False otherwise."""
for item in collection:
if item == target:
return True
return False

The in operator does the same! To create a Boolean expression using in, we write:
6 in [2,4,6,0,1] ⇒ True 1 a value,
7 in [2,4,6,0,1] ⇒ False 2 in,
"y" in "too many geese" ⇒ True
"x" in "too many geese" ⇒ False
3 an iterable such as a str or list.
Exercise

Without using for or if, write a 1-line function is_vowel(ch) that takes a string of
length 1, and determines if it is a vowel (one of a, e, i, o, u, A, E, I, O, U).

Note there are two ways to use the


14/41 keyword
CS 114 - Fall 2023 in:Module
by itself as
4, Section above,
3: Iterating or as part of a for loop.
with for
Algorithm design: Finding the largest
ExerciseExercise

Find the largest value in this list:


[45,27,46,27,69,48,66,49,77,75,15,84,49,53,87,61,32,72,23,37,12,80,79,58,47,19,81]

Now think about your thinking: how did you find it?

Any answer to this question is an algorithm: an explanation of how to solve a problem.


As programmers, a big part of our work is

identifying/inventing the right algorithm, and


turning the algorithm into working code.

Let’s take our rough description and try to make it a bit more precise.

15/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Algorithm design: Finding the largest

We might describe our algorithm to find the largest item in a list as:

“Create a variable that stores the ‘largest item seen so far’; set it to the first item from
the list (or some other item).
Then look at each item in turn; if the new item is larger than the largest item seen so
far, update the largest item seen so far.”

Now we have a detailed algorithm; let’s turn it in to code.

(Note: there is a built-in function max. We want to understand the algorithm, so we are not
going to use it.)

16/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Algorithm design: Finding the largest
Exercise

Write a function longest(items: list[str]) that returns the longest value in items.
[Link]("W", longest(["a", "bee", "was", "on", "a", "green", "leaf"]), "green")

Comparing the values directly with < doesn’t work; that gives us "was".
It takes only a very small change: before comparing, transform each value using len.

17/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Algorithm design: Finding the largest

Suppose I had a list containing a lot of data about cars. How can I find the most reliable
car?
Use same basic process: look at each car, find some “measurement” that meets our
needs. When comparing items, use the measurement. Let’s update our algorithm:

To find in a list the item that is “best” in some sense, create a variable that stores
Procedure

the ‘best item seen so far’; set it to some item from the list (such as the first item).
Then look at each item in turn; if the measurement of the new item is better than
the measurement of the largest item seen so far, update the best item seen so far.

18/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Fancy indexing: slicing

So far we have only indexed an iterable of length L using an integer i : 0 ≤ i < |L|:
word = "foobar" jvj = [2, 4, 6, 0, 1]
word[3] ⇒ "b" jvj[0] ⇒ 2

This is enough for many purposes, but a useful trick is to take a slice of a str or list:

Using a negative index counts from the back.


[-1] gives the last item, [-2] the second last, and so on:
word[-1] ⇒ "r" word[-6] ⇒ "f" jvj[-2] ⇒ 0 jvj[-5] ⇒ 2

Using a single colon like [start:stop] where the first item is item start, stopping just
before stop. If either value is omitted, go to that end:
word[1:4] ⇒ "oob" word[4:] ⇒ "ar" jvj[:2] ⇒ [2,4] jvj[1:-1] ⇒ [4,6,0]

Using two colons like [start:stop:step], as above, but we skip values (and move
backwards with negative step).
word[::2] ⇒ "foa" word[1::2] ⇒ "obr" word[2:5:2] ⇒ "oa" word[::-1] ⇒ "raboof"

19/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Making iterables with +

We can “join” two numbers together using the + operator, making a new number:
2 + 37 + 3 ⇒ 42

We can use this same operator to join two or more strings, making a new string:
"Glory" + "To" + "Ukraine" ⇒ "GloryToUkraine"

Similarly, we can join lists together lists, making a new list:


[2, 4] + [6] + [0, 1] ⇒ [2, 4, 6, 0, 1]
Exercise

Write a function swap_ends(L) that takes a list[any] of length at least 2 and returns a
new list where the first and last value have been swapped.
swap_ends([4, 7, 5, 1, 100]) ⇒ [100, 7, 5, 1, 4]
Hint

Hint: for a list L of length at least 2, L[1:-1] gives a slice that omits the first and last.

20/41 CS 114 - Fall 2023 Module 4, Section 3: Iterating with for


Mutation by index

We saw that we can extract items from a list using indexing, like:
jvj = [2, 4, 6, 0, 1]
jvj[0] ⇒ 2

We can also assign values to an item inside a list, using the same syntax:
jvj[1] = 100
print(jvj)
[2, 100, 6, 0, 1]

What do suppose this code prints? p = [2, 3, 4]


Exercise

q = p
p[0] = 10
print(q)

To mutate is to change. Above, we are changing the list jvj.


Carefully consider a state diagram. p and q are arrows pointing at the same thing!
We are not creating a new list, we are changing this one. We say p is an alias of q.
Mutation and non-mutation

A working solution to swap_ends from earlier: Compare with this:


def swap_ends(L: list[any]) -> list[any]: def swap_ends_mutate(L: list[any]) -> None:
"""Return a list like L but with """Mutate L, swapping first and last."""
first and last swapped.""" last = L[-1]
return [L[-1]] + L[1:-1] + [L[0]] first = L[0]
L[0] = last
mylist = [4, 7, 5, 1, 100] L[-1] = first
## We call: swap_ends(mylist) mylist = [4, 7, 5, 1, 100]
swap_ends(mylist) ⇒ [100, 7, 5, 1, 4] ## We call: swap_ends_mutate(mylist)
mylist ⇒ [4, 7, 5, 1, 100] swap_ends_mutate(mylist) ⇒ None
mylist ⇒ [100, 7, 5, 1, 4]

Notice: the function returns a new list, Notice: the function returns None,
and mylist is unchanged. and mylist is mutated.

! A critically important difference: creating a new list vs mutating an existing list.

22/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Functions and Methods

So far, we have always used a function by passing values to the function as arguments:
abs(-5), or [Link](1.57), or sum_between(6,12).

On some data types, including strings and lists, there are functions called methods that
operate on the data value itself. To use these, we write the name of the variable, a dot,
then the name of the method, with arguments.
For example, [Link](y) returns the index in the string s where the string y first appears, or
-1 if it does not exist.
s = "a man a plan a canal Panama"
[Link]('a') ⇒ 0 # s starts with 'a', so find it at position 0.
[Link]('x') ⇒ -1 # s does not contain 'x', so never find it.
[Link]('n') ⇒ 4
Exercise

Write a function et_first(word: str) -> str. It requires that word contains both 'e' and
't', and returns either 'e' or 't', whichever comes nearer the front of word.
Do not use for or while.
23/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation
Functions and Methods

There are many methods defined on str. Lets see a few more:
s = "a man a plan a canal Panama"

[Link] finds whitespace in a str, and returns a new list[str] of the words:
[Link]() ⇒ ['a', 'man', 'a', 'plan', 'a', 'canal', 'Panama']

if we give it an argument, it splits on that instead of spaces:


[Link]('n') ⇒ ['a ma', ' a pla', ' a ca', 'al Pa', 'ama']

[Link] takes a list[str], and returns a str, joining the values from the list using the
str.
'*'.join(['M', 'A', 'S', 'H']) ⇒ 'M*A*S*H'
''.join(['ma', 'ple', 'sy', 'rup']) ⇒ 'maplesyrup'

Read help(str) to see more.


See that we do not call these like [Link] and [Link].
We have a variable that is a str, and call the method on that variable.
24/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation
Method to mutate a list to add an item: append

With a list L, the method [Link] mutates L, adding a single value at the end:
mylist = [2, 3, 4]
[Link](5)
mylist ⇒ [2, 3, 4, 5]

Often we can start with an empty list, then build an answer using append in a loop:
def countdown(n: int) -> list[int]:
"""Return a list counting down from n to 0."""
answer = []
while n >= 0:
[Link](n)
n = n - 1

return answer

countdown(5) ⇒ [5, 4, 3, 2, 1, 0]

25/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Example: the Collatz sequence in a list

Modify the following code so it returns a list[int] containing the values, instead of
printing them.
def collatz(n: int) -> None:
"""Print the Collatz sequence from n to 1."""
while n != 1:
Exercise

print(n)
if n % 2 == 0:
n = n // 2
else:
n = 3 * n + 1
print(n)
[Link]("C1", collatz(1), [1])
[Link]("C3", collatz(3), [3, 10, 5, 16, 8, 4, 2, 1])
Hint

Start with an empty list, and append something to it each time.

26/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Transforming a list

Replace the ... with only one line of code to make this function work:
def double_each(L: list[int]) -> list[int]:
"""Return a new list containing the double of each item from L."""
Exercise

answer = []
for item in L:
...
return answer

[Link]("D0", double_each([2,4,6,0,1]), [4,8,12,0,2])


Procedure

To make a new list containing values transformed in some way, start with a new
empty list that will be the answer. Loop through the list, transform each value, and
append it to the answer.

27/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Method to mutate a list to remove an item: pop

We use the pop method to remove a single item from a list.


1 To remove the last item use [Link]()
It returns the removed value.
jvj = [2, 4, 6, 0, 1]
[Link]() ⇒ 1 # Remove last item; list now contains [2, 4, 6, 0]
[Link]() ⇒ 0 # Remove last item; list now contains [2, 4, 6]
[Link]() ⇒ 6 # Remove last item; list now contains [2, 4]

2 To remove an item at a particular index, use [Link](index)


jvj = [2, 4, 6, 0, 1]
[Link](4) ⇒ 1 # Remove item number 4; list now contains [2, 4, 6, 0]
[Link](2) ⇒ 6 # Remove item number 2; list now contains [2, 4, 0]
[Link](0) ⇒ 2 # Remove item number 0; list now contains [4, 0]

28/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Method to mutate a list to remove an item: pop

mike = [[["That"], ["Dinkum"], ["Thinkum"]],


Exercise

[["High", "Operational"], ["Logical"]],


[["Multi", "Evaluating"], ["Supervisor"]],
[["Mark", "IV", "Mod", "L"], ["Holmes", "Four"]]]
What does [Link]().pop().pop() evaluate to? How is mike mutated?

30/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


A tuple is an immutable list

Sometimes we want to have a list-like thing that never changes, containing certain types
of values.
For each person we might want to store:

their name, as a str


their year of birth, as an int
their magical possessions, as a list[str].

We always want to store exactly three things. So this is a good place to use a tuple.
We could use a list. But the point of a list is that we can change it—it’s mutable. Here it’s
not.
harry = ("Potter, Harry", 1980, ["Elder Wand", "Resurrection Stone", "Invis. Cloak"])
hermione = ("Granger, Hermione", 1979, ["Time Turner"])
frodo = ("Baggins, Frodo", 2968, ["One Ring", "Sting"])
sam = ("Gamgee, Samwise", 2980, [])

31/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Tuples are immutable lists

There are a few ways to create a tuple:

Write values separated by commas, inside round brackets like (1,2,3).


To create a tuple containing only one item, write a seemingly-useless comma after:
(3,)

Use the tuple function to convert an existing iterable:


tuple([2,4,6,0,1]) ⇒ (2, 4, 6, 0, 1)
tuple('foobar') ⇒ ('f', 'o', 'o', 'b', 'a', 'r')

Use arithmetic, as with lists:


(1,2,3) + (4,5) ⇒ (1, 2, 3, 4, 5)

32/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Working with tuple

Working with a tuple is like working with a list, except we cannot mutate.
Pretty much all we can do is:

extract items by indexing/slicing:


sam[0] ⇒ "Gamgee, Samwise"
frodo[1:] ⇒ (2968, ['One Ring', 'Sting'])

iterate using a for loop:


for thing in hermione:
print(thing)

## We see:
Granger, Hermione
1979
['Time Turner']

We use a tuple mostly to store a fixed group of data. Our algorithms will mostly use lists.
33/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation
Annotating tuples

Generally we work with a tuple of some (short) fixed length.


To annotate, we write tuple[...], replacing the ... with the types of the values in the tuple.
Consider:
harry = ("Potter, Harry", 1980, ["Elder Wand", "Resurrection Stone", "Invis. Cloak"])
hermione = ("Granger, Hermione", 1979, ["Time Turner"])
frodo = ("Baggins, Frodo", 2968, ["One Ring", "Sting"])
sam = ("Gamgee, Samwise", 2980, [])

Each of these contains exactly 3 values: a str, an int, and a list[str].


So each of these is a tuple[str, int, list[str]].

Notice the difference between annotating a list vs a tuple.


! list has only one argument, indicating the type of every value it contains.
tuple has many arguments, one argument for each value it contains.

34/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Counting with range objects

We can already write code to count, using a while loop, like so:
count = 0
while count < 10:
print(count)
count = count + 1

This is OK, but we want to count often. There should be an easier way, and there is: range.
>>> help(range)
Help on class range in module builtins:

class range(object)
| range(stop) -> range object
| range(start, stop[, step]) -> range object
|
| Return an object that produces a sequence of integers from start (inclusive)
| to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
| start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
| These are exactly the valid indices for a list of 4 elements.
| When step is given, it specifies the increment (or decrement).
Counting with range objects

Directly, a range value doesn’t do anything: It isn’t a list. But we can convert it to a list:
vals = range(4) list(vals) ⇒ [0, 1, 2, 3]
print(vals)
## We see:
range(0,4)

I can imagine “every second number from 1000 to 2000,” without writing them all down.
That’s what range is for: range(1000, 2000, 2) represents
[1000, 1002, 1004, 1006, ..., 1998], compactly.

Fill in the blanks ... to create a range object that expands to the desired list:
Exercise

list(range(...)) ⇒ [5,6,7,8]

list(range(...)) ⇒ [40, 45, 50, 55, 60, 65, 70]

list(range(...)) ⇒ [30, 27, 24, 21]

36/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


A for loop using range

We can convert a range object to a list... or iterate directly through it with a for loop.
These snippets do the same thing:

count = 0 for count in range(10):


while count < 10: print(count)
print(count)
count = count + 1

37/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


A for loop using range

Replace the ... with only one line of code to make this function work:
def mutate_double_each(L: list[int]) -> None:
"""Mutate L so each value is doubled."""
Exercise

for i in range(len(L)):
...
return None

thing1 = [2,4,6,0,1]
[Link]("double-r", mutate_double_each(thing1), None)
[Link]("double-m", thing1, [4,8,12,0,2])

Can we generalize? What if we wanted to change the items in some other way?
Procedure

To mutate a list L, transforming each item while keeping the items in the same order,
write for i in range(len(L)):. This uses i as an index.
Inside the loop, transform L[i] as needed.
38/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation
A for loop inside a for loop

Suppose I want to create a table of data, like a times table.


I can represent a single value as a tuple[int, int, int]; for example, (6, 7, 42) can
represent “the product of 6 and 7 is 42”.
I want to make a list of such values, something like:
[(1,1,1), (1,2,2), (1,3,3),
(2,1,2), (2,2,4), (2,3,6),
(3,1,3), (3,2,6), (3,3,9)]

I need to create 3 values like (1, ...), then 3 values like (2, ...), then 3 values like
(3, ...).
Solution: def timestable(size: int) -> list[tuple[int, int, int]]:
answer = []
for row_n in range(1, size+1):
for column_n in range(1, size+1):
[Link]( (row_n, column_n, row_n * column_n) )
# for the tuple: ^ . . . . . . . . . . . . . . . . ^
39/41 return answer CS 114 - Fall 2023 Module 4, Section 4: List Mutation
A for loop inside a for loop

def timestable(size: int) -> list[tuple[int, int, int]]:


answer = []
for row_n in range(1, size+1):
for column_n in range(1, size+1):
[Link]( (row_n, column_n, row_n * column_n) )
# for the tuple: ^ . . . . . . . . . . . . . . . . ^
return answer

Using a similar pattern, write a function even_pairs(n: int) that returns a


list[tuple[int, int]] containing all the pairs of integers (x, y ) where x + y is even.
Exercise

[Link]("EP3", even_pairs(3), [(1,1), (1,3), (2, 2), (3,1), (3,3)])

(Remember, you can tell if an integer is even using the remainder operator:
13 % 2 ⇒ 1 but 14 % 2 ⇒ 0.

40/41 CS 114 - Fall 2023 Module 4, Section 4: List Mutation


Module summary

Use indexing like thing[3] to extract a single value from a str or list, or slicing like
to get a collection of values.
thing[3:4:2]

Write annotations with list[...] and tuple[..., ...].

Use for loops to walk through a str, list, tuple, or range object.
Write code that mutates lists, and that refrains from mutating lists.

Before we begin the next module:


Read and complete the exercises in module 4 of the online textbook, at
[Link]
Complete the module 4 Review Quiz, due on Monday.

41/41 CS 114 - Fall 2023 Module 4, Section 5: Summary

You might also like