我有学生类的对象列表
class Student:
def __init__(self,id,name,cgpa):
self.id=id
self.name=name
self.cgpa=cgpa
def __str__(self):
return "Id:{} Name:{} CGPA:{}".format(self.id,self.name,self.cgpa)
student_objects = [ Student(33,'Rumpa',3.68), Student(85,'Ashis',3.85), Student(56,'Samiha' 3.75), Student(19,'Samara',3.75), Student(22,'Fahim',3.76),]
现在,我必须先按DESCENDING的顺序用cgpa对这些学生对象进行排序。如果两者的cgpa相同,则使用ASCENDING顺序的名称对其进行排序,如果两者名称相同,则使用每个学生唯一的ID对它们进行排序。
通常用于排序,我使用sorted(Iterable,key ='',reverse ='')。但是如何添加CONDITION到下一步,如果两者的cgpa相同,则可以使用它们的名称对其进行排序。
您可以这样做:
>>> list(map(str, sorted(student_objects, key=lambda e: (-e.cgpa, e.name))))
['Id:85 Name:Ashis CGPA:3.85', 'Id:22 Name:Fahim CGPA:3.76', 'Id:19 Name:Samara CGPA:3.75', 'Id:56 Name:Samiha CGPA:3.75', 'Id:33 Name:Rumpa CGPA:3.68']
解析出来:
sorted(student_objects, key=lambda e: (-e.cgpa, e.name))
# key function ^ ^
# Create a tuple ^ ^
# Negative cgpa for descending. ^
# then name ^
您可以使用key=lambda x: (-x.cgpa, x.name)
,但是此技巧仅适用,因为有一种简便的方法可以将int
值映射到颠倒排序顺序的值。
更干净的解决方案是定义一个比较功能,然后使用functools.cmp_to_key
创建一个适当的键功能以供sorted
使用。
from functools import cmp_to_key
def ordering(s1, s2):
if s1.cgpa > s2.cgpa:
return -1 # s1 comes first
elif s1.cgpa < s2.cgpa:
return 1 # s2 comes first
else: # They're equal, fall back to name
if s1.name < s2.name:
return -1
elif s1.name > s2.name:
return 1
else:
return 0
student_objects = [ Student(33,'Rumpa',3.68), Student(85,'Ashis',3.85), Student(56,'Samiha' 3.75), Student(19,'Samara',3.75), Student(22,'Fahim',3.76),]
sorted_students = sorted(student_objects, key=cmp_to_key(ordering))
ordering
可以更简洁地定义:
# Python 2 had this built in.
def cmp(x, y):
return -1 if x < y else 1 if x > y else 0
# Note the order of the arguments in the two calls to cmp
def ordering(s1, s2):
return cmp(s2.cgpa, s1.cgpa) or cmp(s1.name, s2.name)
您可以在您的课程中实现__lt__
函数。
def __lt__(self, other):
if self.cgpa==other.cgpa:
return self.name<other.name
return self.cgpa<other.cgpa
我认为这是您想要的方法
class Student:
def __init__(self,id,name,cgpa):
self.id=id
self.name=name
self.cgpa=cgpa
def __str__(self):
return "Id:{} Name:{} CGPA:{}".format(self.id,self.name,self.cgpa)
student_objects = [ Student(33,'Rumpa',3.68), Student(85,'Ashis',3.85), Student(56,'Samiha', 3.75), Student(19,'Samara',3.75), Student(22,'Fahim',3.76),]
student_objects.sort(key=lambda x: x.cgpa, reverse=False)
for s in student_objects:
print(s.cgpa)