# 集合 之前看到的列表和字符串都是一种有序序列,而集合 `set` 是一种无序的序列。 因为集合是无序的,所以当集合中存在两个同样的元素的时候,Python只会保存其中的一个(唯一性);同时为了确保其中不包含同样的元素,集合中放入的元素只能是不可变的对象(确定性)。 ## 集合生成 可以用`set()`函数来显示的生成空集合: In [1]: ```py a = set() type(a) ``` Out[1]: ```py set ``` 也可以使用一个列表来初始化一个集合: In [2]: ```py a = set([1, 2, 3, 1]) a ``` Out[2]: ```py {1, 2, 3} ``` 集合会自动去除重复元素 `1`。 可以看到,集合中的元素是用大括号`{}`包含起来的,这意味着可以用`{}`的形式来创建集合: In [3]: ```py a = {1, 2, 3, 1} a ``` Out[3]: ```py {1, 2, 3} ``` 但是创建空集合的时候只能用`set`来创建,因为在Python中`{}`创建的是一个空的字典: In [4]: ```py s = {} type(s) ``` Out[4]: ```py dict ``` ## 集合操作 假设有这样两个集合: In [5]: ```py a = {1, 2, 3, 4} b = {3, 4, 5, 6} ``` ### 并 两个集合的并,返回包含两个集合所有元素的集合(去除重复)。 可以用方法 `a.union(b)` 或者操作 `a | b` 实现。 In [6]: ```py a.union(b) ``` Out[6]: ```py {1, 2, 3, 4, 5, 6} ``` In [7]: ```py b.union(a) ``` Out[7]: ```py {1, 2, 3, 4, 5, 6} ``` In [8]: ```py a | b ``` Out[8]: ```py {1, 2, 3, 4, 5, 6} ``` ### 交 两个集合的交,返回包含两个集合共有元素的集合。 可以用方法 `a.intersection(b)` 或者操作 `a & b` 实现。 In [9]: ```py a.intersection(b) ``` Out[9]: ```py {3, 4} ``` In [10]: ```py b.intersection(a) ``` Out[10]: ```py {3, 4} ``` In [11]: ```py a & b ``` Out[11]: ```py {3, 4} ``` In [12]: ```py print(a & b) ``` ```py set([3, 4]) ``` 注意:一般使用print打印set的结果与表示方法并不一致。 ### 差 `a` 和 `b` 的差集,返回只在 `a` 不在 `b` 的元素组成的集合。 可以用方法 `a.difference(b)` 或者操作 `a - b` 实现。 In [13]: ```py a.difference(b) ``` Out[13]: ```py {1, 2} ``` In [14]: ```py a - b ``` Out[14]: ```py {1, 2} ``` 注意,`a - b` 与 `b - a`并不一样,`b - a` 返回的是返回 b 不在 a 的元素组成的集合: In [15]: ```py b.difference(a) ``` Out[15]: ```py {5, 6} ``` In [16]: ```py b - a ``` Out[16]: ```py {5, 6} ``` ### 对称差 `a` 和`b` 的对称差集,返回在 `a` 或在 `b` 中,但是不同时在 `a` 和 `b` 中的元素组成的集合。 可以用方法 `a.symmetric_difference(b)` 或者操作 `a ^ b` 实现(异或操作符)。 In [17]: ```py a.symmetric_difference(b) ``` Out[17]: ```py {1, 2, 5, 6} ``` In [18]: ```py b.symmetric_difference(a) ``` Out[18]: ```py {1, 2, 5, 6} ``` In [19]: ```py a ^ b ``` Out[19]: ```py {1, 2, 5, 6} ``` ### 包含关系 假设现在有这样两个集合: In [20]: ```py a = {1, 2, 3} b = {1, 2} ``` 要判断 `b` 是不是 `a` 的子集,可以用 `b.issubset(a)` 方法,或者更简单的用操作 `b <= a` : In [21]: ```py b.issubset(a) ``` Out[21]: ```py True ``` In [22]: ```py b <= a ``` Out[22]: ```py True ``` 与之对应,也可以用 `a.issuperset(b)` 或者 `a >= b` 来判断: In [23]: ```py a.issuperset(b) ``` Out[23]: ```py True ``` In [24]: ```py a >= b ``` Out[24]: ```py True ``` 方法只能用来测试子集,但是操作符可以用来判断真子集: In [25]: ```py a <= a ``` Out[25]: ```py True ``` 自己不是自己的真子集: In [26]: ```py a < a ``` Out[26]: ```py False ``` ## 集合方法 ### `add` 方法向集合添加单个元素 跟列表的 `append` 方法类似,用来向集合添加单个元素。 ```py s.add(a) ``` 将元素 `a` 加入集合 `s` 中。 In [27]: ```py t = {1, 2, 3} t.add(5) t ``` Out[27]: ```py {1, 2, 3, 5} ``` 如果添加的是已有元素,集合不改变: In [28]: ```py t.add(3) t ``` Out[28]: ```py {1, 2, 3, 5} ``` ### `update` 方法向集合添加多个元素 跟列表的`extend`方法类似,用来向集合添加多个元素。 ```py s.update(seq) ``` 将`seq`中的元素添加到`s`中。 In [29]: ```py t.update([5, 6, 7]) t ``` Out[29]: ```py {1, 2, 3, 5, 6, 7} ``` ### `remove` 方法移除单个元素 ```py s.remove(ob) ``` 从集合`s`中移除元素`ob`,如果不存在会报错。 In [30]: ```py t.remove(1) t ``` Out[30]: ```py {2, 3, 5, 6, 7} ``` In [31]: ```py t.remove(10) ``` ```py --------------------------------------------------------------------------- KeyError Traceback (most recent call last) in () ----> 1 t.remove(10) KeyError: 10 ``` ### pop方法弹出元素 由于集合没有顺序,不能像列表一样按照位置弹出元素,所以`pop` 方法删除并返回集合中任意一个元素,如果集合中没有元素会报错。 In [32]: ```py t.pop() ``` Out[32]: ```py {3, 5, 6, 7} ``` In [33]: ```py print t ``` ```py set([3, 5, 6, 7]) ``` In [34]: ```py s = set() # 报错 s.pop() ``` ```py --------------------------------------------------------------------------- KeyError Traceback (most recent call last) in () 1 s = set() 2 # 报错 ----> 3 s.pop() KeyError: 'pop from an empty set' ``` ### discard 方法 作用与 `remove` 一样,但是当元素在集合中不存在的时候不会报错。 In [35]: ```py t.discard(3) ``` In [36]: ```py t ``` Out[36]: ```py {5, 6, 7} ``` 不存在的元素不会报错: In [37]: ```py t.discard(20) ``` In [38]: ```py t ``` Out[38]: ```py {5, 6, 7} ``` ### difference_update方法 ```py a.difference_update(b) ``` 从a中去除所有属于b的元素: