★本文系正在编写的一本书内容“剧透”。请学习者参考。 ”
数学上,集合之间有“子集”、“超集”的关系和“交、差、并”等运算,在 Python 中也提供了完成集合运算的方法,在程序中恰当使用,可以优化程序。
1. 元素与集合的关系
元素与集合只有一种关系,那就是要么属于某个集合,要么不属于。
代码语言:javascript复制>>> s = set("learn")
>>> s
{'a', 'e', 'r', 'n', 'l'}
>>> 'a' in s
True
>>> 'b' not in s
True
>>> 'b' in s
False
2. 集合与集合的关系
如果两个集合的元素完全一样,那么这两个集合则相等,否则不等——这是集合与集合之间的一种关系。
代码语言:javascript复制>>> a = set([2, 4, 6, 8])
>>> b = set([1, 3, 5, 7])
>>> a == b
False
>>> c = set([2, 4, 6, 8])
>>> a is c
False
>>> a == c
True
此外,还有一种子集(或超集)的关系,如果集合A的所有元素也是集合B的元素,那么A是B的子集,或者说B是A的超集。
代码语言:javascript复制>>> a
{8, 2, 4, 6}
>>> b = set([2, 4, 6, 8, 10])
>>> a.issubset(b) # a 是 b 的子集
True
>>> b.issuperset(a) # b 是 a 的超集
True
从方法命名的角度看, issubset()
和 issuperset()
表达明确,可读性强。但是,如果有读者非常习惯于数学中的运算符号
、
等,会觉得这些符号更简洁明了,为此 Python 也有“同感”,所以提供了如下符号:
代码语言:javascript复制>>> a < b
True
>>> a <= b
True
>>> b > a
True
>>> b >= a
True
这里的 <
、<=
不应视为比较运算符,而是集合运算中的
和
符号,相应地,>
表示
,>=
表示
。
3. 集合间的运算
在数学上,集合之间有并(符号
)、交(符号
)、差(符号
)、对称差(符号
)等运算,在 Python 的集合对象上,也支持这些运算,且有可读性很轻的方法以及对应的符号两套方式。
并
给定集合
、
,定义运算
为:
称为
和
的并集。
Python 中支持运算符号“ |
” 表示数学中的
,也可以使用方法 union()
。
>>> a = set([1, 3, 5])
>>> b = set([3, 6, 9])
>>> a | b
{1, 3, 5, 6, 9}
>>> a.union(b)
{1, 3, 5, 6, 9}
>>> a
{1, 3, 5}
>>> b
{9, 3, 6}
从上述示例可知,集合的并运算生成了一个新的集合对象,并没有修改原有集合对象——下述各项运算均有此特点。
利用符号 |
或者方法 union()
还可以实现多个集合之间的运算。
>>> c = set([2, 4, 6])
>>> a | b | c
{1, 2, 3, 4, 5, 6, 9}
>>> a.union(b, c)
{1, 2, 3, 4, 5, 6, 9}
交
给定集合
、
,定义运算
为:
称为
和
的交集。
Python 中支持运算符号“ &
”表示数学中的
,也可以使用方法 intersection()
。
>>> a
{1, 3, 5}
>>> b
{9, 3, 6}
>>> c
{2, 4, 6}
>>> a & b
{3}
>>> a & b & c
set()
>>> a.intersection(b)
{3}
>>> a.intersection(b, c)
set()
差
给定集合
、
,定义运算
为:
称为
对于
的差集,或相对补集。
如果有全集
,对于
的一个子集
,通常称
为
的补集。
Python 中支持运算符“ -
” 表示数学中的
(都是键盘中的 -
键所对应的符号),也可以使用方法 difference()
。
>>> a
{1, 3, 5}
>>> b
{9, 3, 6}
>>> a - b
{1, 5}
>>> b - a # a - b 不等于 b - a
{9, 6}
>>> a.difference(b)
{1, 5}
>>> b.difference(a)
{9, 6}
上述示例显示,a - b
与 b - a
的结果不同,所以此处的 -
运算的含义与算术运算中的减号含义不同。
对称差
给定集合
、
,定义运算
为:
Python 中支持运算符“ ^
”表示数学中的
,也可以使用方法 symmetric_difference()
。
>>> a
{1, 3, 5}
>>> b
{9, 3, 6}
>>> a ^ b
{1, 5, 6, 9}
>>> a.symmetric_difference(b)
{1, 5, 6, 9}
在使用运算符进行有关集合运算时,参与运算的必须是集合——可变集合或者不可变集合。
代码语言:javascript复制>>> a
{1, 3, 5}
>>> fs = frozenset([2,3,4])
>>> a & fs # (11)
{3}
注释(11)计算了可变集合与不可变集合的交集,Python 会自动先执行 set(fs)
,将不可变集合转换为可变集合,再计算 a & set(fs)
。
但是,如果使用集合的方法 union()
、 intersection()
、 difference()
、 symmetric_difference()
、 issubset()
、 issuperset()
,它们的参数除了集合对象之外,可以是任何可迭代对象——任何可用 set()
创建集合的 Python 对象。
>>> a
{1, 3, 5}
>>> a.union([5, 6, 7])
{1, 3, 5, 6, 7}
>>> a.union({5:'a', 6:'b'})
{1, 3, 5, 6}
>>> a.union("255")
{1, 3, 5, '5', '2'}