Python 的集合关系和运算

2021-07-05 15:33:47 浏览数 (1)

★本文系正在编写的一本书内容“剧透”。请学习者参考。 ”

数学上,集合之间有“子集”、“超集”的关系和“交、差、并”等运算,在 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() 表达明确,可读性强。但是,如果有读者非常习惯于数学中的运算符号

subset

subseteq

等,会觉得这些符号更简洁明了,为此 Python 也有“同感”,所以提供了如下符号:

代码语言:javascript复制
>>> a < b
True
>>> a <= b
True
>>> b > a
True
>>> b >= a
True

这里的 <<= 不应视为比较运算符,而是集合运算中的

subset

subseteq

符号,相应地,> 表示

supset

>= 表示

supseteq

3. 集合间的运算

在数学上,集合之间有并(符号

cup

)、交(符号

cap

)、差(符号

-

)、对称差(符号

vartriangle

)等运算,在 Python 的集合对象上,也支持这些运算,且有可读性很轻的方法以及对应的符号两套方式。

给定集合

A

B

,定义运算

cup

为:

Acup B = {e|ein A 或 e in B}
Acup B

称为

A

B

的并集。

Python 中支持运算符号“ | ” 表示数学中的

cup

,也可以使用方法 union()

代码语言:javascript复制
>>> 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() 还可以实现多个集合之间的运算。

代码语言:javascript复制
>>> 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}

给定集合

A

B

,定义运算

cap

为:

Acap B = {e | ein A 且 e in B }
Acap B

称为

A

B

的交集。

Python 中支持运算符号“ & ”表示数学中的

cap

,也可以使用方法 intersection()

代码语言:javascript复制
>>> 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()

给定集合

A

B

,定义运算

-

为:

A - B = {e|ein A 且 e notin B}
A-B

称为

B

对于

A

的差集,或相对补集。

如果有全集

U

,对于

U

的一个子集

A

,通常称

U-A

A

的补集。

Python 中支持运算符“ - ” 表示数学中的

-

(都是键盘中的 - 键所对应的符号),也可以使用方法 difference()

代码语言:javascript复制
>>> 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 - bb - a 的结果不同,所以此处的 - 运算的含义与算术运算中的减号含义不同。

对称差

给定集合

A

B

,定义运算

vartriangle

为:

Avartriangle B = (A-B)cup(B-A)

Python 中支持运算符“ ^ ”表示数学中的

vartriangle

,也可以使用方法 symmetric_difference()

代码语言:javascript复制
>>> 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 对象。

代码语言:javascript复制
>>> 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'}

0 人点赞