Download as pdf or txt
Download as pdf or txt
You are on page 1of 24

CS1010S Tutorial 6

Lists and Sequences


Quick Recap: List

- Lists are MUTABLE


- lst = [1,2,3]
- lst[2] = 2, [1,2,3] -> [1,2,2]
- lst[2:2] = [3], [1,2,2] -> [1,2,3,2]

- Everything else in tuples applies to lists


Quick Recap: List
- + and * work exactly the same as for tuple.
- Convert with list(seq)
- lst = [1,2,3], Reset for each example.
- lst.append([1,2,3]) -> lst becomes [1,2,3, [1,2,3]] - O(1)
- lst.extend([1,2,3]) -> lst becomes [1,2,3,1,2,3] (Similar to +)
- O(n), n is the length of the input sequence
- lst.insert(1,5) -> lst becomes [1,5,2,3].
- O(n), where n is the number of elements behind the inserted
element
- lst.pop() -> returns 3, lst becomes [1,2] (default to pop(-1))
- lst.pop(1) -> returns 2, lst becomes [1,3]
- https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
Quick Recap: List

- lst.remove(1), lst becomes [2,3]


- Only removes the first matching element
- lst.sort([key=lambda x: x[, reverse=False]])
- sorted(lst, [key=lambda x: x[, reverse=False]])
- Works for tuples as well
- lst.clear(), resets lst to []
For sequences,

- If you have a sequence of fixed length sequences.


- E.g seq = ((1,2), (3,4), (5,6))

for i, j in seq:
print(i, j)
12
34
56
Q1

at_least_n which takes in a list of integers and an integer n, and returns the
original list with all the integers smaller than n removed.

>>> lst = list ( range ( 10 ))

>>> lst2 = at_least_n ( lst , 5 )

>>> lst2

[5 , 6 , 7 , 8 , 9 ]

>>> lst is lst2

True
Q1

def at_least_n(lst, n ): def at_least_n (lst, n):


for i in range(len(lst)): for i in lst:
if lst[i] < n : if i < n:
lst.remove(lst[i]) lst.remove(i)
return lst return lst

Are these implementations correct?


Q1

def at_least_n(lst, n ): def at_least_n (lst, n):


for i in range(len(lst)): for i in lst:
if lst[i] < n : if i < n:
lst.remove(lst[i]) lst.remove(i)
return lst return lst

NEVER mutate a list when iterating through it using for loop.

Implement your own?


Q1

def at_least_n(lst, n):


for i in lst.copy(): ## OR lst[:] OR list(lst)
if i<n:
lst.remove(i)
return lst

What if we want a new list instead?


Q1

def at_least_n(lst,n): def at_least_n(lst, n):


return list(filter(lambda i: i>=n, lst)) new_lst = []
for i in lst:
if i >= n:
new_lst.append(i)
return new_lst
Q2
Q2
def col_sum(m): def col_sum(matrix):
result = [0] * len(matrix[0])
return list(map(sum, zip(*m)))
for row in matrix:
for i in range(len(row)):
def col_sum(m): result[i] += row[i]
result = [] return result
for i in range(len(m[0])):
result.append(sum(map(lambda row:
row[i], m)))
return result
Q2
(b) Write a function row_sum which takes in a matrix and returns a list, where
the i-th element is the sum of the elements in the i-th row of the matrix
Q2
(b) Write a function row_sum which takes in a matrix and returns a list, where
the i-th element is the sum of the elements in the i-th row of the matrix

def row_sum(matrix): def row_sum(m):


result = []
return list(map(sum, m))
for row in matrix:
temp = 0
for item in row:
temp += item
result.append(temp)
return result
Q2

(c) Write a function transpose which takes in a matrix and transposes it.
Basically, this converts an m × n matrix into an n × m matrix.
Q2

(c) Write a function transpose which takes in a matrix and transposes it.
Basically, this converts an m × n matrix into an n × m matrix.
def transpose(m): def transpose(m):

result = [] return list(map(list, zip(*m)))

for i in range(len(m)):
for j in range(len(m[i])):
if len(result) <= j:
result.append([m[i][j]]);
else:
result[j].append(m[i][j])
return result
Q3

- Insertion Sort
- Selection Sort
- Bubble Sort
- Merge Sort
Q4
Q4

def mode_score(students):
# get all scores
scores = list(map(lambda x:x[2], students))
# get the maximum frequency
max_fq = max(map(lambda score: scores.count(score), scores))
# get the scores with the maximum frequncy
mode = list(filter(lambda score: scores.count(score) == max_fq, scores))
# sort them, and retrive each score only once by jumping max_fq at a time
return sorted(mode)[::max_fq]
Q4
Q4

def top_k(students, k):


# sorted is stable so sort name then score
students.sort()
students.sort(key = lambda s: s[2], reverse = True)
threshold = students[k - 1][2] # threshold is the kth student score
return list(filter(lambda stu:stu[2] >= threshold, students))
Extra Question

a = [1,2,3]
b = (1,2,3, a, 4, 5)
print(b)
a.clear()
print(b)
a = [1]
print(b)
Extra Question

a = [1, 2]
a += [a]
b = a.copy()
a[2] = 0
print(a)
print(b)
Extra Question
a = [1, 2]
a += [a]
[1, 2, […]]
if Python is printing a list and discovers that the list is on the stack, that must mean that this
is a self-referential list, and the list should be abbreviated, to avoid an infinite loop.
b = a.copy()
The difference between shallow and deep copying is only relevant for compound objects
(objects that contain other objects, like lists or class instances): A shallow copy constructs a
new compound object and then (to the extent possible) inserts references into it to the
objects found in the original. i.e. print(b) == [1, 2, a]
a[2] = 0
print(a)
print(b)

You might also like