python PTA 1004 成绩排名

你想让某个类的实例支持标准的比较运算(比如>=,!=,<=,<等),但是又不想去实现那一大丢的特殊方法。

Python类对每个比较操作都需要实现一个特殊方法来支持。 例如为了支持>=操作符,你需要定义一个 ge() 方法。 尽管定义一个方法没什么问题,但如果要你实现所有可能的比较方法那就有点烦人了。

装饰器 functools.total_ordering 就是用来简化这个处理的。 使用它来装饰一个来,你只需定义一个 eq() 方法, 外加其他方法(lt(<), le(<=), gt(>), or ge(>=))中的一个即可。 然后装饰器会自动为你填充其它比较方法。

作为例子,我们构建一些房子,然后给它们增加一些房间,最后通过房子大小来比较它们:

from functools import total_ordering


class Room:
    def __init__(self, name, length, width):
        self.name = name
        self.length = length
        self.width = width
        # 不需要传参的就不用在括号里面写了
        self.square_feet = self.length * self.width


@total_ordering
class House:
    def __init__(self, name, style):
        self.name = name
        self.style = style
        self.rooms = list()

    def add_room(self, room):
        self.rooms.append(room)

    @property
    def living_space_footage(self):
        # 因为property 可以直接这样调用函数
        return sum(r.square_feet for r in self.rooms)

    # 最后想要输出什么样的结果
    def __str__(self):
        return '{}: {} square foot {}'.format(self.name,
                                              self.living_space_footage,
                                              self.style)

    def __eq__(self, other):
    # 因为传入了property ,所以直接加点调用就可以了。
        return self.living_space_footage == other.living_space_footage

    def __lt__(self, other):
        return self.living_space_footage < other.living_space_footage


# Build a few houses, and add rooms to them
h1 = House('h1', 'Cape')
h1.add_room(Room('Master Bedroom', 14, 21))
h1.add_room(Room('Living Room', 18, 20))
h1.add_room(Room('Kitchen', 12, 16))
h1.add_room(Room('Office', 12, 12))
h2 = House('h2', 'Ranch')
h2.add_room(Room('Master Bedroom', 14, 21))
h2.add_room(Room('Living Room', 18, 20))
h2.add_room(Room('Kitchen', 12, 16))
h3 = House('h3', 'Split')
h3.add_room(Room('Master Bedroom', 14, 21))
h3.add_room(Room('Living Room', 18, 20))
h3.add_room(Room('Office', 12, 16))
h3.add_room(Room('Kitchen', 15, 17))
houses = [h1, h2, h3]
print('Is h1 bigger than h2?', h1 > h2)  # prints True
print('Is h2 smaller than h3?', h2 < h3)  # prints True
print('Is h2 greater than or equal to h1?', h2 >= h1)  # Prints False
print('Which one is biggest?', max(houses))  # Prints 'h3: 1101-square-foot Split'
print('Which is smallest?', min(houses))  # Prints 'h2: 846-square-foot Ranch'

题目练习
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:
每个测试输入包含 1 个测试用例,格式为

第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
… … …
第 n+1 行:第 n 个学生的姓名 学号 成绩

其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。

输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。

输入样例:

3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95

输出样例:

Mike CS991301
Joe Math990112

代码思路:进行类的比较,需要导入total_ordering,这样比较两个对象就可以了;将所有的实例对象都放在一个列表里,重新建造输入函数__str__,就可以输出想要的结果了。

from functools import total_ordering


@total_ordering
class Student:
    def __init__(self, name, id, score):
        self.name = name
        self.id = id
        self.score = score

    def __eq__(self, other):
        return self.score == other.score

    def __lt__(self, other):
        return self.score < other.score

    def __str__(self):
        return "{0} {1}".format(self.name, self.id)


n = input()
lst = []
for i in range(int(n)):
    line = input()
    line = line.split(" ")
    s = Student(line[0], line[1], int(line[2]))
    lst.append(s)

print(max(lst))
print(min(lst))

###############运行结果####################

3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95


Mike CS991301
Joe Math990112

总结:Python里面一切皆对象,所以对象也可以作为函数的参数使用。

发布了25 篇原创文章 · 获赞 2 · 访问量 834

猜你喜欢

转载自blog.csdn.net/Di_Panda/article/details/105151416