对于Python中对象列表进行排序时,我们往往需要根据对象中的属性进行特定的排序。
首先我们假设一个类为:
class Student:
def __init__(self, name, score, age):
self.name = name
self.score = score
self.age = age
def __str__(self):
return self.name + " " + str(self.score) + " " + str(self.age)
然后,要求为:先按年龄从大到小排序,年龄相同的按成绩从高到低排,成绩相同的,按姓名从小到大排。
这里可以看到,我们对于对象的三个属性,有从大到小的,也有从小到大的,因此比较复杂,首先我们可以尝试使用列表的sort()函数,但是sort()如果没有参数传递的话,就只能进行简单数据的排序,因此我们还需要用到一个方法——attrgetter()
:
from operator import attrgetter
n = int(input())
student = []
for i in range(n):
temp = input().split()
student.append(Student(temp[0], int(temp[1]), int(temp[2])))
# 对student列表按照age,score,name的优先次序进行排序
student.sort(key=attrgetter("age", "score", "name"), reverse=True)
其中attrgetter("age", "score", "name")
的意思是,先按照age进行排序,如果age一样,则按照score排序,如果score也一样,则按照name排序。
给定输入为:
5
Kitty 56 22
Hanmeimei 70 21
Alice 70 21
Joey 89 22
Tim 19 25
可以看到,输出结果对于age和score的排序要求已经达到了,但是name的排序结果是从大到小,而不是从小到大,这是因为我们前面统一进行了反转(reverse)。
因此我们需要将age,score和name分别进行排序:
student.sort(key=attrgetter("name"), reverse=False)
student.sort(key=attrgetter("age", "score"), reverse=True)
即先对name进行从小到大排序,再对age,score进行从大到小排序,注意:千万不要反过来
可以看到,最终输出结果符合要求