《Python Cookbook(第3版)中文版》——1.14 对不原生支持比较操作的对象排序...

    xiaoxiao2024-01-23  155

    本节书摘来自异步社区《Python Cookbook(第3版)中文版》一书中的第1章,第1.14节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.14 对不原生支持比较操作的对象排序

    1.14.1 问题

    我们想在同一个类的实例之间做排序,但是它们并不原生支持比较操作。

    1.14.2 解决方案

    内建的sorted()函数可接受一个用来传递可调用对象(callable)的参数key,而该可调用对象会返回待排序对象中的某些值,sorted则利用这些值来比较对象。例如,如果应用中有一系列的User对象实例,而我们想通过user_id属性来对它们排序,则可以提供一个可调用对象将User实例作为输入然后返回user_id。示例如下:

    >>> class User: ... def __init__(self, user_id): ... self.user_id = user_id ... def __repr__(self): ... return 'User({})'.format(self.user_id) ... >>> users = [User(23), User(3), User(99)] >>> users [User(23), User(3), User(99)] >>> sorted(users, key=lambda u: u.user_id) [User(3), User(23), User(99)] >>>

    除了可以用lambda表达式外,另一种方式是使用operator.attrgetter()。

    >>> from operator import attrgetter >>> sorted(users, key=attrgetter('user_id')) [User(3), User(23), User(99)] >>>

    1.14.3 讨论

    要使用lambda表达式还是attrgetter()或许只是一种个人喜好。但是通常来说,attrgetter()要更快一些,而且具有允许同时提取多个字段值的能力。这和针对字典的operator.itemgetter()的使用很类似(参见1.13节)。例如,如果User实例还有一个first_name和last_name属性的话,可以执行如下的排序操作:

    by_name = sorted(users, key=attrgetter('last_name', 'first_name'))

    同样值得一提的是,本节所用到的技术也适用于像min()和max()这样的函数。例如:

    >>> min(users, key=attrgetter('user_id') User(3) >>> max(users, key=attrgetter('user_id') User(99) >>> 相关资源:python cookbook(第3版)
    最新回复(0)