集合運算
交集運算
存在集合A和B, 對於集合C, 如果C的每個元素即是A的元素, 又是B的元素, 並且A和B所有相同的元素都在C找到, 那麼C是A和B的交集。具體請參考如下實例。
交集運算方法:
- s1.intersection(s2)
- s1.intersection_update(s2):_update版本, 原地修改, 返回None
- &:s1 & s2,也叫交集運算符重載
實例1:s1.intersection(s2)
In [82]: s1 = {1, 2, 3}
In [83]: s2 = {2, 3, 4}
In [84]: s1.intersection(s2) # 交集
Out[84]: {2, 3}
In [85]: s2.intersection(s1) # 不修改原來的兩個集合, 返回新的集合
Out[85]: {2, 3}
In [86]: s1
Out[86]: {1, 2, 3}
In [87]: s2
Out[87]: {2, 3, 4}
實例2:s1.intersection_update(s2)
In [88]: s1.intersection_update(s2) # _update版本, 原地修改, 返回None, 等效於s1 = s1.intersection(s2)
實例3:s1 & s2
In [89]: s1
Out[89]: {2, 3}
In [90]: s2
Out[90]: {2, 3, 4}
In [91]: s1 = {1, 2, 3}
In [92]: s1 & s2 # set重載按位與運算符爲求交集運算, 等效於s1.intersection(s2)
Out[92]: {2, 3}
In [93]: s2 & s1
Out[93]: {2, 3}
差集運算
結合A和B, 當集合C的元素僅存於A中, 但不存在B中, 並且A中存在B中不存在的元素全部存在C中, 那麼C是A和B的差集。
差集運算方法:
- s1.difference(s2):求s1和s2的差集部分
- s1.difference_update(s2):_update版本原地修改, 返回None
- -:s1 - s2或者s2 - s1,也叫差集運算符重載
差集沒有交換律
實例1:s1.difference(s2)
In [86]: s1
Out[86]: {1, 2, 3}
In [87]: s2
Out[87]: {2, 3, 4}
In [94]: s1.difference(s2) # 差集,求s1和s2的差集部分,意思是s1和s2對比,返回s1在s2沒有的部分
Out[94]: {1}
結合A和B, 當集合C的元素僅存於A中, 但不存在B中, 並且A中存在B中不存在的元素全部存在C中, 那麼C是A和B的差集。
實例2:s2.difference(s1)
In [95]: s2.difference(s1) # 差集沒有交換律,求s2和s1的差集部分
Out[95]: {4}
實例3:s1.difference_update(s2)
In [96]: s1.difference_update(s2) # _update版本原地修改, 返回None, 相當於s1 = s1.difference(s2)
In [97]: s1
Out[97]: {1}
In [98]: s2
Out[98]: {2, 3, 4}
In [99]: s1 = {1, 2, 3}
實例4:s1 - s2
In [100]: s1 - s2 # set重載了運算符"-"執行差集計算, 相當於s1.difference(s2)
Out[100]: {1}
In [101]: s2 - s1
Out[101]: {4}
補集計算
如果把兩個集合A和B看成是一個全集, 對稱差集是交集的補集。
補集也叫對稱差集。
補集運算方法:
- s1.symmetric_difference(s2)對稱差集
- s1.symmetric_difference_update(s2),原地修改, 返回None
- ^:s1 ^ s2:補集的運算符重載
對稱差集具有交換律
如下圖:集合A和集合B不相交的部分
In [102]: s1.symmetric_difference(s2) # 對稱差集
Out[102]: {1, 4}
In [103]: s2.symmetric_difference(s1) # 對稱差集具有交換律
Out[103]: {1, 4}
In [104]: s1.symmetric_difference_update(s2) 原地修改, 返回None, 相當於None s1 = s1.symmetric_difference(s2)
In [105]: s1 = {1, 2, 3}
In [106]: s1 ^ s2 # set重載了異或運算符, 執行對稱差集運算, 相當於s1.symmetric_difference(s2)
Out[106]: {1, 4}
並集計算
給定兩個集合A,B,把他們所有的元素合併在一起組成的集合,叫做集合A與集合B的並集
並集運算方法:
- s1.union(s2)
- s1.update(s2)並集的update版本
- |:並集的運算符重載
In [107]: s1.union(s2) # 並集計算
Out[107]: {1, 2, 3, 4}
In [108]: s2.union(s1) # 有交換律
Out[108]: {1, 2, 3, 4}
In [109]: s1.update(s2) # 並集的update版本
In [110]: s1
Out[110]: {1, 2, 3, 4}
In [111]: s1 + s2 # 集合並沒有重載加法運算符
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-111-1659087814e1> in <module>()
----> 1 s1 + s2
TypeError: unsupported operand type(s) for +: 'set' and 'set'
In [112]: s1 | s2 # set重載了按位或運算符, 用於並集計算
Out[112]: {1, 2, 3, 4}
集合的四種運算
補集的定義依賴於全集, python沒有全集, 自然沒有補集。
全集不是運算, 全集是定義出來的。
本圖片來自於:https://blog.csdn.net/sxingming/article/details/51922776
集合相關的判斷
- s2.issubset(s1):判斷s2是否是s1的子集
- s1.issuperset(s2):判斷s1是否是s2的超集
- 元素一樣, 即是子集, 又是超集。比如這樣s1.issuperset(s1)
- s1.isdisjoint(s2):判斷兩個集合是否有交集, 如果有交集返回False, 沒有交集返回True
In [113]: s1 = {1, 2, 3, 4}
In [114]: s2 = {2, 3}
集合A裏的所有元素都能在集合B裏找到, 那麼A是B的子集, B是A的超集
In [115]: s2.issubset(s1) # 判斷s2是否是s1的子集
Out[115]: True
In [116]: s1.issubset(s2)
Out[116]: False
In [117]: s1.issuperset(s2) # 判斷s1是否是s2的超集
Out[117]: True
In [118]: s1.issubset(s1) # 元素一樣, 即是子集, 又是超集
Out[118]: True
In [119]: s1.issuperset(s1)
Out[119]: True
issubset的實現
In [120]: def issubset(s1, s2):
...: for x in s1:
...: if x not in s2:
...: return False
...: return True
...:
issuperset的實現
In [3]: def issuperset(s1, s2):
...: for x in s2:
...: if x not in s1:
...: return False
...: return True
...:
In [3]: s1.isdisjoint(s2) # 判斷兩個集合是否有交集, 如果有交集返回False, 沒有交集返回True
Out[3]: False
In [4]: s3 = {1, 2}
In [5]: s4 = {3, 4}
In [6]: s3.isdisjoint(s4)
Out[6]: True
集合的應用
- 場景1:有一個api, 它需要認證, 並且有一定的權限纔可以訪問, 例如要求滿足權限A, B, C中任意一項, 有一個用戶具有權限B, C, D, 那麼此用戶是否有權限訪問此API。
- 場景2:有一個任務列表, 存儲全部的任務, 有一個列表, 存儲已經完成的任務, 找出未完成的任務。
集合的限制
集合的特性, 元素不會重複
哪些數據結構對元素有限制?
- 集合能輸入str、int、元組、bytes等
- 集合不能輸入列表、bytearray、集合
In [7]: {'a', 'b', 'c'} # 集合能輸入文本
Out[7]: {'a', 'b', 'c'}
In [8]: {1, 'b'} # 集合能輸入數字及文本
Out[8]: {'b', 1}
In [9]: {1, 2, 3} # 集合能輸入數字
Out[9]: {1, 2, 3}
In [10]: {[1, 2, 3], [2, 3, 4]} # 列表不能是集合的元素
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-7ca6f92cfb85> in <module>()
----> 1 {[1, 2, 3], [2, 3, 4]}
TypeError: unhashable type: 'list'
In [11]: {bytearray(b'abc')} # bytearray不能是集合的元素
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-62b530a8195b> in <module>()
----> 1 {bytearray(b'abc')}
TypeError: unhashable type: 'bytearray'
In [12]: {{3}} # 集合不能是集合的元素
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-dbb470487147> in <module>()
----> 1 {{3}}
TypeError: unhashable type: 'set'
In [13]: {(1, 2)} # 元組可以做爲集合的元素
Out[13]: {(1, 2)}
In [14]: {b'abc'} # bytes可以做爲集合的元素
Out[14]: {b'abc'}
In [16]: hash(b'abc') # bytes是可hash的
Out[16]: 7310675750012804621
In [17]: hash(1) # 數字是可hash
Out[17]: 1
In [18]: hash([1, 2, 3]) # 列表是不可hash的
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-18-0b995650570c> in <module>()
----> 1 hash([1, 2, 3])
TypeError: unhashable type: 'list'
目前我們所知道的所有的可變類型都是不可hash的, 所有的不可變類型都是可hash
hash是調用了元素的方法:
In [20]: 1.__hash__()
集合和集合操作總結
增加:
add
update
刪除:
remove
discard
pop
clear
集合判斷:
超集:
issuperset
子集:
isubset
交集:
isdisjoint
集合運算
交:
intersection
intersection_update
&
並:
union
update
|
差:
difference
difference_update
-
對稱差集
symmetric_difference
symmetric_difference_update