# [2021-Fall] Lab06 of CS61A of UCB

## Mutability

Write a function which takes in a list lst, an argument entry, and another argument elem. This function will check through each item in lst to see if it is equal to entry. Upon finding an item equal to entry, the function should modify the list by placing elem into lst right after the item. At the end of the function, the modified list should be returned.

See the doctests for examples on how this function is utilized.

Important: Use list mutation to modify the original list. No new lists should be created or returned.

Note: If the values passed into entry and elem are equivalent, make sure you're not creating an infinitely long list while iterating through it. If you find that your code is taking more than a few seconds to run, the function may be in a loop of inserting new values.

def insert_items(lst, entry, elem):
is_the_same = (entry == elem)
while True:
no_entry = True
for i in range(len(lst)):
if lst[i] == entry:
if i == len(lst) - 1:
lst.append(elem)
else:
lst.insert(i + 1, elem)
no_entry = False
# avoid infinite loop
if is_the_same:
i += 1
if no_entry:
return lst


def insert_items(lst, entry, elem):
"""Inserts elem into lst after each occurence of entry and then returns lst.

>>> test_lst = [1, 5, 8, 5, 2, 3]
>>> new_lst = insert_items(test_lst, 5, 7)
>>> new_lst
[1, 5, 7, 8, 5, 7, 2, 3]
>>> double_lst = [1, 2, 1, 2, 3, 3]
>>> double_lst = insert_items(double_lst, 3, 4)
>>> double_lst
[1, 2, 1, 2, 3, 4, 3, 4]
>>> large_lst = [1, 4, 8]
>>> large_lst2 = insert_items(large_lst, 4, 4)
>>> large_lst2
[1, 4, 4, 8]
>>> large_lst3 = insert_items(large_lst2, 4, 6)
>>> large_lst3
[1, 4, 6, 4, 6, 8]
>>> large_lst3 is large_lst
True
>>> # Ban creating new lists
>>> from construct_check import check
>>> check(HW_SOURCE_FILE, 'insert_items',
...       ['List', 'ListComp', 'Slice'])
True
"""
pos, cnt = 0, 0
for i in lst:
if i == entry:
cnt += 1

while cnt > 0:
idx = lst.index(entry, pos)
pos = idx + 1
if idx == len(lst) - 1:
lst.append(elem)
else:
lst.insert(idx + 1, elem)
cnt -= 1
return lst


## Iterators

### Q4: Count Occurrences

Implement count_occurrences, which takes in an iterator t and returns the number of times the value x appears in the first n elements of t. A value appears in a sequence of elements if it is equal to an entry in the sequence.

Note: You can assume that t will have at least n elements.

def count_occurrences(t, n, x):
"""Return the number of times that x appears in the first n elements of iterator t.

>>> s = iter([10, 9, 10, 9, 9, 10, 8, 8, 8, 7])
>>> count_occurrences(s, 10, 9)
3
>>> s2 = iter([10, 9, 10, 9, 9, 10, 8, 8, 8, 7])
>>> count_occurrences(s2, 3, 10)
2
>>> s = iter([3, 2, 2, 2, 1, 2, 1, 4, 4, 5, 5, 5])
>>> count_occurrences(s, 1, 3)
1
>>> count_occurrences(s, 4, 2)
3
>>> next(s)
2
>>> s2 = iter([4, 1, 6, 6, 7, 7, 8, 8, 2, 2, 2, 5])
>>> count_occurrences(s2, 6, 6)
2
"""
it = iter(t)
cnt = 0
while n > 0:
val = next(it)
if val == x:
cnt += 1
n -= 1
return cnt


### Q5: Repeated

Implement repeated, which takes in an iterator t and returns the first value in t that appears k times in a row.

Note: You can assume that the iterator t will have a value that appears at least k times in a row. If you are receiving a StopIteration, your repeated function is likely not identifying the correct value.

Your implementation should iterate through the items in a way such that if the same iterator is passed into repeated twice, it should continue in the second call at the point it left off in the first. An example of this behavior is in the doctests.

1. 如何找到连续的 k 个值 ? 需要设置 last_val 来记住上一个值是什么, 这样才能和当前的值进行对比. 用一个 while True: 来不断找即可(题目保证一定找得到, 所以不用怕死循环)
2. 如何保证下一次调用的时候要从上一次离开的位置开始 ? 如果认真看过课程的人可能记得要怎么做, 我们应该用高阶函数, 在 repeated 里面再定义一个函数, 将变量绑定到这个嵌套的函数上. 这样我们就可以保证每次都可以从上一次的位置开始. 忘了的可以看看这个链接 的 2.4.4 Local state
def repeated(t, k):
"""Return the first value in iterator T that appears K times in a row.
Iterate through the items such that if the same iterator is passed into
the function twice, it continues in the second call at the point it left
off in the first.

>>> s = iter([10, 9, 10, 9, 9, 10, 8, 8, 8, 7])
>>> repeated(s, 2)
9
>>> s2 = iter([10, 9, 10, 9, 9, 10, 8, 8, 8, 7])
>>> repeated(s2, 3)
8
>>> s = iter([3, 2, 2, 2, 1, 2, 1, 4, 4, 5, 5, 5])
>>> repeated(s, 3)
2
>>> repeated(s, 3)
5
>>> s2 = iter([4, 1, 6, 6, 7, 7, 8, 8, 2, 2, 2, 5])
>>> repeated(s2, 3)
2
"""
assert k > 1
last_val, it = None, iter(t)
def helper(k):
nonlocal last_val
nonlocal it
cnt = 0

while True:
val = next(it)

if last_val is None or val != last_val:
last_val, cnt = val, 1
else:
cnt += 1
if cnt == k:
return val
return helper(k)

posted @ 2022-02-21 00:35  MartinLwx  阅读(1374)  评论(0编辑  收藏  举报