1.14 排序不支持原生比較的對(duì)象

2018-02-24 15:26 更新

問(wèn)題

你想排序類型相同的對(duì)象,但是他們不支持原生的比較操作。

解決方案

內(nèi)置的 sorted() 函數(shù)有一個(gè)關(guān)鍵字參數(shù) key ,可以傳入一個(gè) callable 對(duì)象給它,這個(gè) callable 對(duì)象對(duì)每個(gè)傳入的對(duì)象返回一個(gè)值,這個(gè)值會(huì)被 sorted 用來(lái)排序這些對(duì)象。比如,如果你在應(yīng)用程序里面有一個(gè)User實(shí)例序列,并且你希望通過(guò)他們的user_id屬性進(jìn)行排序,你可以提供一個(gè)以User實(shí)例作為輸入并輸出對(duì)應(yīng)user_id值的 callable 對(duì)象。比如:

class User:
    def __init__(self, user_id):
        self.user_id = user_id

    def __repr__(self):
        return 'User({})'.format(self.user_id)

def sort_notcompare():
    users = [User(23), User(3), User(99)]
    print(users)
    print(sorted(users, key=lambda u: u.user_id))

另外一種方式是使用 operator.attrgetter() 來(lái)代替lambda函數(shù):

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

討論

選擇使用lambda函數(shù)或者是 attrgetter() 可能取決于個(gè)人喜好。但是,attrgetter() 函數(shù)通常會(huì)運(yùn)行的快點(diǎn),并且還能同時(shí)允許多個(gè)字段進(jìn)行比較。這個(gè)跟 operator.itemgetter() 函數(shù)作用于字典類型很類似(參考1.13小節(jié))。例如,如果User實(shí)例還有一個(gè)first_name和last_name屬性,那么可以向下面這樣排序:

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

同樣需要注意的是,這一小節(jié)用到的技術(shù)同樣適用于像 min()max() 之類的函數(shù)。比如:

>>> min(users, key=attrgetter('user_id')
User(3)
>>> max(users, key=attrgetter('user_id')
User(99)
>>>
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)