Python排序代码的语法
我需要做的是
写一个叫做 top_k 的函数,这个函数接收一个学生名单和一个整数 k,然后返回一个包含前 k 名得分最高的学生名字的列表,并且这些名字要按字母顺序排列。如果有其他学生的得分和第 k 名学生相同,也要把他们的名字包含在列表里。
比如当我输入
top_k(student_list1, 5)
>>> [('eugene', 'A', 21), ('simon', 'A', 21), ('john', 'A', 15), ('tiffany', 'A', 15), ('dave', 'B', 12)]
top_k(student_list2, 3)
>>>[('eugene', 'A', 21), ('simon', 'A', 21), ('john', 'A', 15), ('tiffany', 'A', 15)]
其中的
student_list1 = [('tiffany', 'A', 15),
('jane', 'B', 10),
('ben', 'C', 8),
('simon', 'A', 21),
('eugene', 'A', 21),
('john', 'A', 15),
('jimmy', 'F', 1),
('charles', 'C', 9),
('freddy', 'D', 4),
('dave', 'B', 12)]
student_list2 = [('tiffany', 'A', 15),
('jane', 'B', 10),
('ben', 'C', 8),
('john', 'A', 15),
('simon', 'A', 21),
('eugene', 'A', 21)]
我的代码是
def top_k(students, k):
toptobottom = sorted(students, key = lambda x: x[2], reverse = True)
takeout= toptobottom[:k+1]
result = []
for takethat in takeout:
if takethat[2] == 21:
result.append(takethat)
result.sort( key= lambda x: x[0])
elif takethat[2] ==15:
result.append(takethat)
return result
我不太确定 result.sort( key ..) 应该放在哪里。它应该和 elif 在同一行吗,还是需要缩进?谢谢!
3 个回答
1
你只需要对输入的数组进行一次排序,然后再选择合适的学生。
def top_k(students, k):
toptobottom = sorted(students, key = lambda x: (-x[2], x[0]))
length = len(toptobottom)
if k >= 0 and k < length:
result = toptobottom[:k]
i = k
else:
result = toptobottom
i = 0
k = 1
while i < length and toptobottom[i][2] == toptobottom[k-1][2]:
result.append(toptobottom[i])
i += 1
return result
1
除了你缩进的问题,你的代码是专门为输入的数据写的(也就是说,最高分数在你的函数里是硬编码的)。虽然这样可能让你完成这个练习,但这并不是一个好的编程习惯,你应该更一般性地考虑你要解决的问题。
用伪代码表示:
def top_k(students, k):
create a blank output list
for each student in the list of students sorted in reverse order by score:
if either ((we have fewer than k students in the output so far) or
(the student equals the score of the last student in output)):
add the student to the output
otherwise:
stop looping
return the output sorted by name
0
这并不是一个答案,所以我不想让它被标记成答案,但我想补充一些内容,这些内容可能对你将来很有帮助,评论里写不下。
关于你的问题:
def top_k(students, k):
toptobottom = sorted(students, key = lambda x: x[2], reverse = True)
takeout= toptobottom[:k+1]
result = []
for takethat in takeout:
if takethat[2] == 21:
result.append(takethat) # I indented this
result.sort( key= lambda x: x[0])
elif takethat[2] ==15:
result.append(takethat)
return result
我觉得我帮你调整了一下缩进,但我没有分析你的逻辑。我看到你用的是硬编码的分数,就停下来了,因为这样做真的很糟糕。千万不要这样做,绝对不要。尤其是在你做算法课的作业的时候。
第二点是,我觉得你不应该完全忽视一些Python的资源,Python的标准库里关于排序的资源非常丰富,还有很多库可以帮助你。
第三,Python的库和内置类型的完整性做得很好,我真的觉得你应该去看看。
第四,我根据你的例子准备了一些小代码片段。当然,我没有把它们整理成一个完整的函数,因为我希望你能思考一下你在做什么。我相信这些对你会很有帮助。
from operator import itemgetter, attrgetter
from copy import deepcopy
student_list1 = [('tiffany', 'A', 15),
('jane', 'B', 10),
('ben', 'C', 8),
('simon', 'A', 21),
('eugene', 'A', 21),
('john', 'A', 15),
('jimmy', 'F', 1),
('charles', 'C', 9),
('freddy', 'D', 4),
('dave', 'B', 12)]
def get_sorted(student_list):
q = sorted(student_list1, key=itemgetter(2,0), reverse=True)
# Now that the list is sorted according to score and
# name reversed, (meaning that while simon and eugene
# will both be at the top, simon will always come first
# we need to swap nearby names according to their value.
for i in xrange(0, len(q)-1):
if q[i][0] > q[i+1][0] and q[i][2] is q[i+1][2]:
temp = q[i+1]
q[i+1] = q[i]
q[i] = temp
return q
print 'correct sorted order'
for i in get_sorted(student_list1):
print i
q = get_sorted(student_list1)
our_dict = dict.fromkeys( [x[2] for x in q], [] )
for i in q:
our_dict[i[2]] = our_dict[i[2]] + [i]
print 'grouped together'
print our_dict
# this gets some number of records from the dict
# according to the specifications of your program
def get_some(number):
buff = []
for i in sorted(our_dict.keys(), reverse=True):
if len(buff) < number:
buff += our_dict[i]
return buff
print "let's get \'five\' elements from the list, like in your example"
print get_some(5)
print
print "let's get \'three\' elements from the list, like in your example"
print get_some(3)
这是输出结果:
correct sorted order
('eugene', 'A', 21)
('simon', 'A', 21)
('john', 'A', 15)
('tiffany', 'A', 15)
('dave', 'B', 12)
('jane', 'B', 10)
('charles', 'C', 9)
('ben', 'C', 8)
('freddy', 'D', 4)
('jimmy', 'F', 1)
grouped together
{1: [('jimmy', 'F', 1)], 4: [('freddy', 'D', 4)], 8: [('ben', 'C', 8)], 9: [('charles', 'C', 9)], 10: [('jane', 'B', 10)], 12: [('dave', 'B', 12)], 15: [('john', 'A', 15), ('tiffany', 'A', 15)], 21: [('eugene', 'A', 21), ('simon', 'A', 21)]}
let's get 'five' elements from the list, like in your example
[('eugene', 'A', 21), ('simon', 'A', 21), ('john', 'A', 15), ('tiffany', 'A', 15), ('dave', 'B', 12)]
let's get 'three' elements from the list, like in your example
[('eugene', 'A', 21), ('simon', 'A', 21), ('john', 'A', 15), ('tiffany', 'A', 15)]
你觉得能把这些结合起来,完成作业并更好地理解吗?这里面有一些复杂的东西,比如字典、列表和列表推导式,但我觉得这是一个很好的汇总,展示了Python如何轻松解决几乎所有的列表问题。