08-01集合運算

集合運算

交集運算

存在集合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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章