【Python 祕籍】排序不支持原生比較的對象

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

解決方案
內置的 sorted() 函數有一個關鍵字參數 key ,可以傳入一個 callable 對象給它, 這個 callable 對象對每個傳入的對象返回一個值,這個值會被 sorted 用來排序這些對象。 比如,如果你在應用程序裏面有一個 User 實例序列,並且你希望通過他們的 user_id 屬性進行排序, 你可以提供一個以 User 實例作爲輸入並輸出對應 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 函數:

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

```討論
選擇使用 lambda 函數或者是 attrgetter() 可能取決於個人喜好。 但是, attrgetter() 函數通常會運行的快點,並且還能同時允許多個字段進行比較。 這個跟 operator.itemgetter() 函數作用於字典類型很類似(參考上篇帖子)。 例如,如果 User 實例還有一個 first_name 和 last_name 屬性,那麼可以像下面這樣排序:

```bash
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知識,請訪問藝賽旗社區:https://support.i-search.com.cn/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章