将python中的类对象与指定条件进行比较

问题描述 投票:0回答:4

我有学生类的对象列表

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相同,则可以使用它们的名称对其进行排序。

python list sorting oop iterable
4个回答
0
投票

您可以这样做:

>>> 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                                     ^

0
投票

您可以使用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)

0
投票

您可以在您的课程中实现__lt__函数。

def __lt__(self, other):
    if self.cgpa==other.cgpa:
        return self.name<other.name

    return self.cgpa<other.cgpa

-1
投票

我认为这是您想要的方法

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)
© www.soinside.com 2019 - 2024. All rights reserved.