在之前的python学习过程中我们学习了基本的python语法以及一些基础应用,相信在大家的努力下对于python已经有了一定程度的了解,为了迎合时代浪潮,基础的python学习已经无法满足我们的日常生产生活,所以在这里我将和大家一同学习python拔高知识,体验python之美。
笔者赠言:长风破浪会有时,直挂云帆济沧海。
下面是与python相关的经典拔高习题,望同学们认真学习哈。
1.经典python习题
定义一个名为print_border(word, spaces)的函数,它接受两个参数。第一个参数是一个字符串,打印时应该用星号(*)包围。第二个参数表示打印边框时,单词的每一边(左边和右边)应该出现多少个空格。
可以假设单词的长度至少为1,空格的值大于或等于0。
例如:
Test | Result |
print_border('hello', 3) | ************** hello ************** |
print_border('compsci 130', 1) | **************** compsci 130 **************** |
def print_border(word, spaces):
space = spaces * ' '
print('*' * (len(word) + 2 + (spaces * 2)))
print('*' + space + word + space + '*')
print('*' * (len(word) + 2 + (spaces * 2)))
定义一个名为unique_letters(word_a, word_b)的函数,该函数以两个单词作为参数。该函数应返回一个包含单词中所有字母的字符串,但不应包括两个单词中都存在的任何字母。换句话说,它应该包含只出现在一个单词中的字母。每个字母应该在结果字符串中只出现一次,并且这些字母应该按字母顺序排列。
例如:
Test | Result |
print(unique_letters('hello', 'world')) | dehrw |
print(unique_letters('abc', 'bbccdd')) | ad |
def unique_letters(word_a, word_b):
result = ''
for letter in word_a:
if letter not in word_b and letter not in result:
result += letter
for letter in word_b:
if letter not in word_a and letter not in result:
result += letter
return ''.join(sorted(result))
定义一个名为get_longest_length(values_list)的函数,它接受一个整数列表作为输入。该函数应计算并返回列表中最长的连续非零值序列的长度。例如,考虑以下列表:
values = [3, 6, 12, 0, 0, 9, 10, 5, 5, 0, 2, 1, 3, 0, 9]
在这个列表中,有四个不同的值序列,由零值分隔:
3 6 12(长度为3)
9 10 5 5(长度是4)
2 1 3(长度为3)
9(长度为1)
在本例中,最长序列的长度为4,因此函数应该返回4。
您可以假设输入列表包含至少一个非零整数。
例如:
Test | Result |
values = [3, 6, 12, 0, 0, 9, 10, 5, 5, 0, 2, 1, 3, 0, 9]result = get_longest_length(values)print(result) | 4 |
result = get_longest_length([100])print(result) | 1 |
def get_longest_length(values):
longest = 0
run = 0
for v in values:
if v == 0:
if run > longest:
longest = run
run = 0
else:
run += 1
return max(longest, run)
定义一个名为get_pair_sum_over(numbers_list, target_sum)的函数,该函数以一个整数列表和一个目标和作为参数。该函数应该返回一个唯一的2元素元组排序列表,其中元组中的每个值都来自参数列表,并且2个元组元素的和大于参数目标和。
注意:
参数列表可能包含重复的值。
参数列表中的每对值只能在元组列表中出现一次。例如,如果参数列表是[3,2,1],目标和是4,那么输出元组列表将只包含元组(2,3)而不包含元组(3,2)。
元组列表必须是升序的,每个元组中的元素也必须是升序的。
例如:
Test | Result |
result = get_pair_sum_over([4, 6, 2, 7, 3, 2, 3, 7], 8)print(type(result))print(result) | <class 'list'>[(2, 7), (3, 6), (3, 7), (4, 6), (4, 7), (6, 7), (7, 7)] |
print(get_pair_sum_over([4, 6, 2, 7, 3, 4, 1, 5, 9, 6], 12)) | [(4, 9), (5, 9), (6, 7), (6, 9), (7, 9)] |
print(get_pair_sum_over([4, 7, 8, 9, 3, 2, 6, 11, 1, 5, 10], 14)) | [(4, 11), (5, 10), (5, 11), (6, 9), (6, 10), (6, 11), (7, 8), (7, 9), (7, 10), (7, 11), (8, 9), (8, 10), (8, 11), (9, 10), (9, 11), (10, 11)] |
def get_pair_sum_over(numbers_list, target_sum):
numbers_list.sort()
result = []
for i in range(len(numbers_list) - 1):
for j in range(i+1, len(numbers_list)):
if numbers_list[i] + numbers_list[j] > target_sum:
a_tuple = (numbers_list[i], numbers_list[j])
if a_tuple not in result:
result.append((numbers_list[i], numbers_list[j]))
#result.sort()
return result
异常处理问题
定义一个名为get_total_cost(items_dict, items_list)的函数,它接受两个参数作为输入。第一个参数是一个字典,其中键表示待售商品的名称,值表示该商品的成本。第二个参数是包含要购买的商品名称的列表。该函数应计算与要购买的所有项目相关的总成本。
例如,如果项目名称和成本的字典是:
items = {'apple': 12, 'banana': 7, 'cherry': 10, 'dragonfruit': 35}
要购买的物品清单是:
selected = ['apple', 'apple', 'cherry', 'dragonfruit', 'cherry']
那么总费用应该是79。
但是,在计算总开销时,你必须防范两种类型的异常:
KeyError:如果列表中的项不是字典中的有效键,就会发生这种情况
TypeError:如果字典中某项的代价不是一个数字(在这种情况下,加法将失败),就会发生这种情况。
您应该通过忽略任何无效值来处理任何异常。您应该计算所有有效值的结果。
你的函数应该返回一个元组,由:
总成本
处理的keyerror数目
处理的TypeErrors的数目
def get_total_cost(items, selected):
result = 0
key_errors = 0
type_errors = 0
for i in selected:
try:
result += items[i]
except KeyError:
key_errors += 1
except TypeError:
type_errors += 1
return result, key_errors, type_errors
python的类问题
定义一个名为Song的类,它存储有关歌曲的标题、艺术家和歌曲长度的信息。Song类定义了以下数据字段:
一个名为self的数据字段。定义歌曲标题的标题。
一个名为self的数据字段。艺术家定义了一首歌的艺术家。
一个名为self的整数数据字段。定义歌曲长度的Song_length。
此外,该类必须具有以下功能:
根据标题,艺术家和歌曲长度创建一个Song对象。参数中的歌曲长度格式为“分钟:秒”。初始化器将参数song length转换为秒。例如:
- song1 = Song('Bloom', 'Radiohead', '5:15') #5:15 -> song length = 315
返回代表歌曲信息的字符串。例如,代码:print(song1)
将产生以下输出:
"Bloom" by Radiohead(315)
注意:在下面的回答框中提交整个类定义。
例如:
Test | Result |
song1 = Song('Bloom','Radiohead',"5:15")print(song1)print(type(song1)) | "Bloom" by Radiohead(315)<class '__main__.Song'> |
song1 = Song('Morning Mr Magpie','Radiohead','4:41')print(song1) | "Morning Mr Magpie" by Radiohead(281) |
class Song:
def __init__(self, title, artist, length):
self.title = title
self.artist = artist
data = length.split(":")
length_min = int(data[0])
length_second = int(data[1])
self.song_length = length_min * 60 + length_second
def __str__(self):
return '"{}" by {}({})'.format(self.title, self.artist, self.song_length)
定义一个名为Album的类,用于存储关于歌曲列表的信息。Album类定义了以下数据字段: 一个名为self.name的数据字段,它定义了一个相册的名称。 一个名为self的数据字段。定义专辑中歌曲列表的Songs_list。 此外,该类必须具有以下功能: 创建一个相册。例如: my_own_album = Album("My own Album") 向相册中添加一首歌。例如: s1 = Song(“Bloom”,“Radiohead”,“5:15”) s2 = Song(《早上,喜鹊先生》,《电台司令》,《4:41》) my_own_album.add_song (s1) my_own_album.add_song (s2) 返回一个表示专辑信息的字符串。该方法应该打印专辑名称和歌曲列表。如果列表为空,则该方法应该打印专辑的名称,并在后面加上“列表为空!”例如,语句:print(my_own_album) 将产生以下输出:
My own Album: "Bloom" by Radiohead(315) "Morning Mr Magpie" by Radiohead(281)
该类还应该提供一个以秒为单位获取歌曲总长度的功能。例如,下面的代码:print(my_own_album.get_total_song_length ()) 将产生以下输出: 596 注意:假设给出了Song类,请在下面的回答框中提交整个类定义。
class Song:
def __init__(self, title, artist, song_length):
self.__title = title
self.__arist = artist
self.__song_length = song_length
lis = self.__song_length.split(":")
self.__song_length = int(lis[0])*60+int(lis[1])
def __str__(self):
return '"{}" by {}({})'.format(self.__title, self.__arist, self.__song_length)
def get_length(self):
return self.__song_length
class Album:
def __init__(self, name):
self.__name = name
self.__songs_list = []
def add_song(self, song):
self.__songs_list.append(song)
def __str__(self):
if len(self.__songs_list) != 0:
st = "{}:\n".format(self.__name)
for i in self.__songs_list:
st += str(i) +"\n"
st = st[:-1]
return "{}".format(st)
else:
st = "{}:\n".format(self.__name)
st += "The list is empty!"
return "{}".format(st)
def get_total_song_lengths(self):
num = 0
for i in self.__songs_list:
num += i.get_length()
return num
从前面任务的解决方案开始,通过实现remove_songs_by_artist(self, artist)方法扩展Album类。该方法以艺术家名称作为参数,并从该参数artist录制的所有歌曲中删除。例如,如果一张专辑包含以下歌曲:
'Morning Mr Magpie' by Radiohead 'Sour Times' by Portishead' 'Separator' by Radiohead'
以下代码片段:
album.remove_songs_by_artist('Radiohead') print(album)
输出:
My Album: "Sour Times" by Portishead(251)
注意:假设给出了Song类,请在下面的回答框中提交整个类定义。
class Song:
def __init__(self, title, artist, song_length):
self.__title = title
self.__arist = artist
self.__song_length = song_length
lis = self.__song_length.split(":")
self.__song_length = int(lis[0])*60+int(lis[1])
def __str__(self):
return '"{}" by {}({})'.format(self.__title, self.__arist, self.__song_length)
def get_length(self):
return self.__song_length
def get_arist(self):
return self.__arist
class Album:
def __init__(self, name):
self.__name = name
self.__songs_list = []
def add_song(self, song):
self.__songs_list.append(song)
def __str__(self):
if len(self.__songs_list) != 0:
st = "{}:\n".format(self.__name)
for i in self.__songs_list:
st += str(i) +"\n"
st = st[:-1]
return "{}".format(st)
else:
st = "{}:\n".format(self.__name)
st += "The list is empty!"
return "{}".format(st)
def get_total_song_lengths(self):
num = 0
for i in self.__songs_list:
num += i.get_length()
return num
def remove_songs_by_artist(self, artist):
for i in range(len(self.__songs_list)-1, -1, -1):
if self.__songs_list[i].get_arist() == artist:
self.__songs_list.remove(self.__songs_list[i])
python堆栈问题
重要提示:对于这个问题,您将定义一个使用堆栈ADT的函数。作为这个问题的一部分,提供给你一个堆栈实现——你不应该定义自己的堆栈类。相反,你的代码可以使用任何Stack ADT方法:Stack(), push(), pop(), peek(), size()和is_empty()。
编写一个名为remove_negatives(stack)的函数,该函数接受一个参数:stack。您可以假设Stack只包含整数(或者为空)。该函数应该从堆栈中删除所有的负值(即小于0的整数),让所有其他值保持原来的顺序。
例如:
Test | Result |
s1 = Stack()s1.push(1)s1.push(2)s1.push(-3)s1.push(4)s1.push(5)print(s1)remove_negatives(s1)print(s1) | [1, 2, -3, 4, 5 <-[1, 2, 4, 5 <- |
s1 = Stack()s1.push(-1)s1.push(2)s1.push(-3)s1.push(4)s1.push(-5)print(s1)remove_negatives(s1)print(s1) | [-1, 2, -3, 4, -5 <-[2, 4 <- |
def remove_negatives(s):
s1 = Stack()
while not s.is_empty():
x = s.pop()
if x >= 0:
s1.push(x)
while not s1.is_empty():
s.push(s1.pop())
python队列问题
重要提示:对于这个问题,您将定义一个使用Queue ADT的函数。队列实现作为这个问题的一部分提供给您—您不应该定义自己的queue类。相反,您的代码可以使用任何Queue ADT方法:Queue(), enqueue(), dequeue(), peek(), size()和is_empty()。
编写一个名为jump_queue(queue, value)的函数,该函数接受两个参数:一个queue和一个要在队列中搜索的值。如果该值确实存在于队列中,那么它应该被移动到队列的前面。如果该值在队列中出现了多次,那么只应该将最靠近队列前端的值移动到队列前端。如果该值已经位于队列的前面,或者该值在队列中不存在,则不应修改队列。
例如:
Test | Result |
q1 = Queue()q1.enqueue(1)q1.enqueue(2)q1.enqueue(3)q1.enqueue(4)q1.enqueue(5)print(q1)jump_queue(q1, 5)print(q1) | -> |5, 4, 3, 2, 1| ->-> |4, 3, 2, 1, 5| -> |
q1 = Queue()q1.enqueue(1)q1.enqueue(2)q1.enqueue(3)q1.enqueue(4)q1.enqueue(5)print(q1)jump_queue(q1, 1)print(q1) | -> |5, 4, 3, 2, 1| ->-> |5, 4, 3, 2, 1| -> |
def jump_queue(q, value):
q1 = Queue()
found = None
while not q.is_empty():
x = q.dequeue()
if found is None and x == value:
found = x
else:
q1.enqueue(x)
if found is not None:
q.enqueue(found)
while not q1.is_empty():
q.enqueue(q1.dequeue())
python节点问题
定义一个名为cumulative_sum(node)的函数,该函数以node对象(对链接的节点链的引用)作为参数。该函数改变节点链中的其余元素,使每个元素都是链中前面节点的累积和。例如,如果节点链是:1 ->2→3,则节点链变为1 ->3→6.
注意:可以假设参数是一个有效的Node对象。该函数对节点链进行更改,并且不返回任何内容。
重点:在本练习中,您将定义一个使用Node ADT的函数。Node实现是作为练习的一部分提供给您的—您不应该定义自己的Node类。相反,您的代码可以使用任何Node ADT字段和方法。
例如:
Test | Result |
node1 = Node(4)node2 = Node(3, node1)node3 = Node(2, node2)node4 = Node(1, node3)print_node_chain(node4)cumulative_sum(node4)print_node_chain(node4) | 1 2 3 41 3 6 10 |
node1 = Node(5)node2 = Node(10, node1)node3 = Node(30, node2)node4 = Node(40, node3)cumulative_sum(node4)print_node_chain(node4) | 40 70 80 85 |
def cumulative_sum(node):
current = node
value = 0
while current:
value += current.data
current.data = value
current = current.next
python链表问题
通过添加方法interleave(self, other)来扩展下面给出的LinkedList类,该方法以链表作为参数。该方法以交替的方式将参数链表合并到自身中,从自身的第一个项开始,然后从参数链表的第一个项开始。可以假设链表本身和参数链表的长度相等。例如,如果链表本身是1 →3,参数链表为2 →4,然后该方法将自己更新为1→2→3→4。
注意:
不应该在链表中添加/删除任何元素。您应该只更改下一个数据字段的引用。使用上面的例子,第一个节点(1)本身的下一个字段应该指向参数链表中的第一个节点(2)。参数链表的第一个节点(2)的下一个字段应该指向它自己的第二个节点(3),以此类推。
提交整个LinkedList类定义。您可以假设给出了Node类。
例如:
Test | Result |
list1 = LinkedList()list1.add(3)list1.add(1)list2 = LinkedList()list2.add(4)list2.add(2)list1.interleave(list2)print(list1)print(type(list1)) | 1, 2, 3, 4<class '__main__.LinkedList'> |
s1 = LinkedList()for i in range(1, 6): s1.add(i)s2 = LinkedList()word = 'hello'for ch in word: s2.add(ch)s1.interleave(s2)print(s1) | 5, o, 4, l, 3, l, 2, e, 1, h |
class LinkedList:
def __init__(self):
self.head = None
def get_head(self):
return self.head
def get_next(self):
return self.head.get_next()
def set_next(self, node):
self.head.set_next(node)
def is_empty(self):
return self.head == None
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.next
return count
def add(self, item):
new_node = Node(item)
new_node.set_next(self.head)
self.head = new_node
def __str__(self): # assume not empty
result = ""
current = self.head
while current:
result = result + str(current.data) + ", "
current = current.next
return result[:-2]
def interleave(self, other):
a_node = LinkedList()
other = other.get_head()
while not self.is_empty():
a_node.add(self.head)
a_node.add(other.get_data())
self.head = self.head.get_next()
other = other.get_next()
self.head = a_node.get_head()
b_node = LinkedList()
while not self.is_empty():
b_node.add(self.head)
self.head = self.head.get_next()
self.head =b_node.get_head()
python 二叉树
定义一个名为cumulative_sum(树)的递归函数,该函数以二叉树作为参数。该函数使用二叉树中每个节点的子节点的累积和更新其值。这个函数更新参数二叉树。它不会创建新的树。例如,考虑下面的二叉树:
3 (L) 2 (L) 4 (R) 5 (R) 8 (R) 9 (R) 6
该函数更新了二叉树,结果是:
37 (L) 28 (L) 9 (R) 5 (R) 17 (R) 9 (R) 6
根结点是37,因为28(左子树的累积和)+ 3(本身)+ 6(右子树的累积和)是37。
注意:
作为练习的一部分,我们提供了一个BinaryTree实现——你不应该定义自己的BinaryTree类。相反,您的代码可以使用BinaryTree ADT数据字段和方法。
您可以假设树中的值都是整数。
例如:
Test | Result |
print_tree(tree1, 0)cumulative_sum(tree1)print_tree(tree1, 0) | 7(L) 2(L) 1(R) 5(R) 9(R) 1438(L) 8(L) 1(R) 5(R) 23(R) 14 |
def cumulative_sum(t):
if t == None:
return 0
else:
sum_of_tree = int(t.data)
if t.left != None:
sum_of_tree += cumulative_sum(t.left)
if t.right != None:
sum_of_tree += cumulative_sum(t.right)
t.data = sum_of_tree
return sum_of_tree
python二叉搜索树
定义一个名为get_list(tree)的递归函数,该函数以二叉搜索树作为参数。该函数应返回一个Python列表,其中包含参数二叉搜索树的顺序遍历值。
可以假设参数二叉搜索树不是空的。
重要提示:在本练习中,您将定义一个使用BinarySearchTree ADT的函数。一个BinarySearchTree实现作为练习的一部分提供给你——你不应该定义你自己的BinarySearchTree类。相反,您的代码可以使用BinarySearchTree ADT字段和方法中的任何一个。
例如:
Test | Result |
print_tree(tree1, 0)print(get_list(tree1)) | 7(L) 2(L) 1(R) 5(R) 9[1, 2, 5, 7, 9] |
def get_list(tree):
if tree == None:
return []
lis = []
if tree.get_left() != None:
lis += get_list(tree.get_left())
lis += [tree.get_data()]
if tree.get_right() != None:
lis += get_list(tree.get_right())
return lis
继续上一个问题,定义一个名为get_list_beneath(bst, value)的函数,该函数以一个二叉搜索树和一个整数值作为参数。该函数应该返回树中包含指定值的节点(即该节点的左右子树)下面的所有数据值的列表。如果函数中指定的值在树中不存在,则函数应该返回一个空列表。例如,考虑下面的二叉搜索树:
7 / \ / \ 2 9 / \ / \ 1 5
代码:print(get_list_beneath(tree1, 2)) returns:
[1,5]
注意:你可以假设二叉搜索树不是空的,并且给出了get_list()函数。
注意:一个BinaryTree的实现是作为练习的一部分提供给你的——你不应该定义你自己的BinaryTree类。相反,您的代码可以使用BinaryTree ADT的任何属性和方法。这些方法包括data、left和right属性、get_data和set_data方法、get_left和set_left方法以及get_right和set_right方法。
提供了一个get_node函数,它将返回BST中匹配给定值的节点,如果不存在这样的节点,则返回None。
例如:
Test | Result |
print_tree(tree2, 0)print(get_list_beneath(tree2, 5)) | 27(L) 14(L) 10(R) 19(R) 35(L) 31(R) 42[] |
print(get_list_beneath(tree2, 14)) | [10, 19] |
print(get_list_beneath(tree2, 42)) | [] |
def get_list(tree):
if tree == None:
return []
lis = []
if tree.get_left() != None:
lis += get_list(tree.get_left())
lis += [tree.get_data()]
if tree.get_right() != None:
lis += get_list(tree.get_right())
return lis
def find_node(bst, value):
if bst.data == value:
return bst
elif value < bst.data and bst.left != None:
return find_node(bst.left, value)
elif value > bst.data and bst.right != None:
return find_node(bst.right, value)
else:
return None
def get_list_beneath(t, value):
tree = find_node(t, value)
if tree == None:
return []
else:
lis = get_list(tree)
if value in lis:
lis.remove(value)
return lis
python学习到此已经告一段落,希望同学们可以在之后的时日继续勤奋学习,做到熟能生巧,争取早日成为技术大拿,笔者在此与大家共勉。