1.14 排序不支持原生比較的對象

2018-02-24 15:26 更新

問題

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

解決方案

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

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() 來代替lambda函數(shù):

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

討論

選擇使用lambda函數(shù)或者是 attrgetter() 可能取決于個人喜好。但是,attrgetter() 函數(shù)通常會運行的快點,并且還能同時允許多個字段進(jìn)行比較。這個跟 operator.itemgetter() 函數(shù)作用于字典類型很類似(參考1.13小節(jié))。例如,如果User實例還有一個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)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號