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