【2017-09-08】數據結構與算法(七)

序列

  • 刪除相同元素并保持序列順序
    問題*怎樣在一個序列上面保持元素順序的同時消除重復的值?
    方案:
    • 利用集合,但是不維護序列的順序,無序
    • 利用sorted() 、min()、max()等內置函數思想,自定義一個函數
#示例:使用集合:對結果的順序無要求,可以考慮
>>> list1=[1,3,4,3,4,2,1,8]
>>> set(list1)
{8, 1, 2, 3, 4}
>>> list3=[(1,2),(2,3),(1,2)]
>>> set(list3)
{(1, 2), (2, 3)}
>>>

?? 由上述例子可見,集合去掉重復元素后,不能保持原有的順序,這也是集合的特性。
?? 如果需要既要消除重復元素,又要維持序列原有的順序,可參考sorted()等內置函數的思想,結合集合自定義一個返回生成器的函數。

#示例1:列表去重并保持順序
>>> def dedup(items):
    setp=set()
    for i in items:
        if i not in setp:
            yield i
            setp.add(i)

            
>>> dedup(list1)
<generator object dedup at 0x022AE330>
>>>#當結果足夠大時,盡量不要直接轉換成list,這里只是示例
>>> list(dedup(list1))
[1, 3, 4, 2, 8]

?? 如果序列的元素為字典類型呢?用上述方法不可用,理由是序列元素(字典)不屬于hashable類型,需要將字典變成hashable類型,換言之,將鍵值對轉化成元組形式。
引申概念
?? 什么是可哈希(hashable)的?一個 object 是可哈希的(hashable),是指這個 object 在其生存期內有一個不變的哈希值(hash value),即hash() 方法返回的值。

示例2:元素為字典類型的序列
>>> list1=[1,3,4,3,4,2,1,8]
>>> list2=[{'x':1,'y':2},{'x':1,'y':3},{'x':1,'y':5},{'x':1,'y':2}]
>>> def dedup(items,key=None):
    setp=set()
    for item in items:
        val=item if key is None else  key(item )
        if val not in setp:
            yield val
            setp.add(val)
>>> list(dedup(list1))
[1, 3, 4, 2, 8]
>>> for i in dedup(list2,key=lambda x:(x['x'],x['y'])):
    print(i)
    
(1, 2)
(1, 3)
(1, 5)
>>> 
  • 對象不支持原生的比較操作
    問題:如果你想排序同類對象,但是元素的比較操作不支持直接比較?
    方案:
    ?? 在類實例對象中,利用sorted()函數關鍵字參數key特性,可以傳入一個 callable 對象給它,這個 callable 對象對每個傳入的對象返回一個值,這個值會被 sorted 用來排序這些對象。
    ?? key對應函數的實現
    ?? ?? - lambda匿名函數實現
    ?? ?? - operator模塊attrgetter()函數實現,支持多個字段進行排序。用法類似用于字典的 operator.itemgetter()
#示例
>>> from operator import attrgetter
>>> 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 user:user.user_id)
[User(3), User(23), User(99)]
>>> sorted(users,key=attrgetter('user_id'))
[User(3), User(23), User(99)]
>>> 

總結
?? 數據結構與算法這一章節基本學習結束,大部分內容基本理解,少部分內容不甚理解,待后續學習的深入,再回頭看看。通過最近每天學習一點點,最大的感受是豁然開朗:思路更開闊,想法更多。回顧以前寫的腳本或者正在寫的腳本,仍有很多地方需要改善,怎么讓代碼更優雅、更簡潔、可讀、不重復造輪子,仍然值得進一步思考。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容