Python高级语法-详解set机制
生活随笔
收集整理的這篇文章主要介紹了
Python高级语法-详解set机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
集合過濾機制
文章目錄
- 集合過濾機制
- 簡介
- Set詳解
- Set使用
- 補充說明
簡介
- 底層分析set的實現原理。
- 詳細分析Python的set容器如何過濾自定義類。
- 代碼實現多熟悉自定義類的按照指定屬性使用set進行過濾。
Set詳解
- Python的set容器又叫可哈希的集合,核心算法為hash算法。其原理可以理解為有多個桶,每個桶是一個數組類型的容器,通過hash值快速定位在哪個桶,通過eq方法比較是否已經存在該對象在桶內,不在則放入該桶(注意判斷是否存在該桶對象默認eq方法比較的是對象的id值)。
- 主要流程如下。
- 調用對象的__hash__方法計算對象的hash值,確定該對象放到哪個桶中。
- 調用對象的__eq__方法對比桶內對象是否和當前對象相等,不等則添加進去。
Set使用
- 基礎使用
- s = set() s.add(1) s.add(2) s.add(3) s.add(1) print(s)
- 可以看到,對基礎數據類型,直接對值取hash值,對值進行eq(=)判斷,可以很方便使用set進行過濾。
- 自定義類
- __eq__方法
- class Foo(object):def __init__(self, a, b):self.a = aself.b = bdef __eq__(self, other):return self.a == other.a and self.b == other.bobj1 = Foo(1, 2)obj2 = Foo(1, 2)print(obj1 == obj2)print(obj1 is obj2)
- 這里重寫了相等判斷的方法,"=="運算符的結果就是調用這個方法得到結果。但是,"is"運算符的結果是比較兩個對象的id(可以理解為物理地址的映射值),不同的對象在內存中地址一定不同,id值也就不同。
- __hash__方法
- class Foo(object):def __init__(self, a, b):self.a = aself.b = bdef __eq__(self, other):return self.a == other.a and self.b == other.bobj1 = Foo(1, 2)obj2 = Foo(1, 2)obj3 = Foo(2, 1)s = set()s.add(obj1)s.add(obj2)s.add(obj3)
- 執行上面這段代碼會報錯TypeError: unhashable type: 'Foo',這是因為自定義的類沒有實現__hash__方法,無法得到對象的hash值就不能確定“桶”的位置。
- 完整實現
- class Foo(object):def __init__(self, a, b):self.a = aself.b = bdef __eq__(self, other):return self.a == other.a and self.b == other.bdef __hash__(self):return hash(self.a + self.b)obj1 = Foo(1, 2)obj2 = Foo(1, 2)obj3 = Foo(2, 1)s = set()s.add(obj1)s.add(obj2)s.add(obj3)for item in s:print("a:", item.a, "b:", item.b)
- 這里重寫了__hash__和__eq__方法,注意,為了區分開不同對象,hash取值的屬性一定要合理,要以自己的需求為目的(這里只有a和b分別相同就認為是“同一個對象”)。對a和b的和取hash值,和相同的在一個桶,進而判斷是否eq所需方法相等。顯然,obj2被過濾掉了。
- __eq__方法
補充說明
- 本腳本運行環境為Python3.6,要求Python版本必須達到Python3.4以上。
- 這里只是進行了運行機制的解釋,底層實現較為繁瑣,不做敘述。
- 實現自定義類的對象按照部分屬性利用set過濾,如有錯誤,歡迎指正。
總結
以上是生活随笔為你收集整理的Python高级语法-详解set机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DenseNet详述
- 下一篇: Pandas条件筛选 | Python技