开源图书《Python完全自学教程》5.2.4集合的关系和运算

2022-05-17 09:40:32 浏览数 (1)

5.2.4 集合的关系和运算

数学上,集合之间有“子集”、“超集”的关系和“交、差、并”等运算,在 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

此外,还有一种子集(或超集)的关系,如图5-2-1所示,如果集合 A 的所有成员也是集合 B 的,那么 A 是 B 的子集,或者说 B 是 A 的超集。

图5-2-1 子集(超集)

代码语言: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() 表达明确,可读性强。但是,如果有读者非常习惯于数学中的运算符号 subsetsubseteq 等,会觉得这些符号更简洁明了,为此 Python 也有“同感”,所以提供了如下符号:

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

这里的 <<= 不应视为比较运算符,而是集合运算中的 subset subseteq 符号,相应地,> 表示 supset>= 表示 supseteq

3. 集合间的运算

在数学上,集合之间有并(符号 cup )、交(符号 cap )、差(符号 - )、对称差(符号 vartriangle )等运算,在 Python 的集合对象上,也支持这些运算,且有可读性很强的方法以及对应的符号两套方式。

给定集合 AB ,定义运算 cup 为:

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

Acup B称为 AB 的并集。

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}

给定集合 AB ,定义运算 cap 为:

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

Acap B称为 AB 的交集。

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()

给定集合 AB ,定义运算 - 为:

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

A-B称为 B 对于 A 的差集,或相对补集。

如果有全集 U ,对于 U 的一个子集 A ,通常称 U-AA 的补集。

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}

对称差

给定集合 AB ,定义运算 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'}

自学建议 从开始自学到现在,一直在学 Python 的内置对象类型,有的读者可能会质疑:这些东西怎么用?甚至有的人会认为,这样的自学方式太慢了。 现代社会生活节奏比较快,为了迎合我们的这种感觉,就有了诸如“X天学会某某”的广告满天飞——其中 X 是不能大于21的,因为有人说21天会改掉一个坏习惯并养成一个好习惯,虽然这并未得到严格证实,但很多人相信——这无疑对本来焦虑的人们雪上加霜。 不过,我们还是要理智地思考:学习能不能“快餐化”?或许有的内容可以。根据我个人经验,至少在编程语言的学习中,“快餐化”地学习,貌似在较短时间内入门,实则只是照葫芦画瓢——以所谓的实战项目自欺欺人。所以,请读者稍安勿躁,打牢基础,养成独立研习的习惯,掌握学习方法,假以时日,必能厚积薄发,前途无量。 ”

0 人点赞