概述
一. 集合论
集合的本质是许多唯一对象的聚集,因此,集合可以用于去重:
集合中的元素必须是可散列的,set 类型本身是不可散列的,但是 frozenset 可以。除了保证唯一性,集合还实现了很多基础的中缀运算符。给定两个集合 a 和 b,a | b 返回的是它们的合集,a & b 得到的是交集,而 a - b 得到的是差集。
演示1 needles 的元素在 haystack 里出现的次数,两个变量都是 set 类型
演示2 needles 的元素在 haystack 里出现的次数,这次的代码可以用在任何可迭代对象上
以上的所有例子的运行时间都能在 3 毫秒左右,在含有 10 000 000 个元素的 haystack 里搜索 1000 个值,算下来大概是每个元素 3 微秒。除了速度极快的查找功能(这也得归功于它背后的散列表),内置的 set 和 frozenset 提供了丰富的功能和操作,不但让创建集合的方式丰富多彩,而且对于 set 来讲,我们还可以对集合里已有的元素进行修改。
1.1 集合字面量
除空集之外,集合的字面量——{1}、{1, 2},等等——看起来跟它的数学形式一模一样。如果是空集,那么必须写成 set() 的形式,如果只是写成 {} 的形式,跟以前一样,你创建的其实是个空字典。
像 {1, 2, 3} 这种字面量句法相比于构造方法(set([1, 2, 3]))要更快且更易读。用 dis.dis(反汇编函数)来看看两个方法的字节码的不同:
特殊的字节码 BUILD_SET 几乎完成了所有的工作。而使用set()创建时,3 种不同的操作代替了上面的 BUILD_SET:LOAD_NAME、BUILD_LIST 和 CALL_FUNCTION。
由于 Python 里没有针对 frozenset 的特殊字面量句法,我们只能采用构造方法:
1.2 集合推导
演示2 新建一个 Latin-1 字符集合,该集合里的每个字符的 Unicode 名字里都有“SIGN”这个单词
从 unicodedata 模块里导入 name 函数,用以获取字符的名字。把编码在 32~255 之间的字符的名字里有“SIGN”单词的挑出来,放到一个集合里。
1.3 集合的操作
列出了可变和不可变集合所拥有的方法的概况,其中不少是运算符重载的特殊方法。
中缀运算符需要两侧的被操作对象都是集合类型,但是其他的所有方法则只要求所传入的参数是可迭代对象。例如,想求 4 个聚合类型 a、b、c 和 d 的合集,可以用 a.union(b, c, d),这里 a 必须是个 set,但是 b、c 和 d 则可以是任何类型的可迭代对象。
表 1-1:集合的数学运算:这些方法或者会生成新集合,或者会在条件允许的情况下就地修改集合
数学符号 | Python运算符 | 方法 | 描述 |
S ∩ Z | s & z | s.__add__(z) |
s
和
z
的交集
|
z & s | s.__radd__(z) |
反向
&
操作
| |
s.intersection(it, ...)
|
把可迭代的
it
和其他所有参数转化为集合,然后求它们与 s 的交集
| ||
s &= z
| s.__iand__(z) |
把
s
更新为
s
和
z
的交集
| |
s.intersection_update(it, ...)
|
把可迭代的
it
和其他所有参数转化为集合,然后求得它们与 s 的交集,然后把
s
更新成这个交集
| ||
S
∪ Z
|
s | z
| s.__or__(z) |
s
和
z
的并集
|
z | s
| s.__ror__(z) |
|
的反向操作
| |
s.union(it, ...) |
把可迭代的
it
和其他所有参数转化为集合,然后求它们和 s 的并集
| ||
s |= z
| s.__ior__(z) |
把
s
更新为
s
和
z
的并集
| |
s.update(it, ...) |
把可迭代的
it
和其他所有参数转化为集合,然后求它们和 s 的并集,并把 s
更新成这个并集
| ||
S Z
| s - z | s.__sub__(z) |
s
和
z
的差集,或者叫作相对补集
|
z - s | s.__rsub__(z) |
-
的反向操作
| |
s.difference(it, ...)
|
把可迭代的
it
和其他所有参数转化为集合,然后求它们和 s 的差集
| ||
s -= z | s.__isub__(z) |
把
s
更新为它与
z
的差集
| |
s.difference_update(it, ...)
|
把可迭代的
it
和其他所有参数转化为集合,求它们和 s
的差集,然后把 s
更新成这个差集
| ||
s.symmetric_difference(it)
|
求
s
和
set(it)
的对称差集
| ||
S
△ Z
|
s ^ z
| s.__xor__(z) |
求
s
和
z
的对称差集
|
z ^ s
| s.__rxor__(z) |
^
的反向操作
| |
s.symmetric_difference_update(it, ...)
|
把可迭代的
it
和其他所有参数转化为集合,然后求它们和 s 的对称差集,最后把 s
更新成该结果
| ||
s ^= z
| s.__ixor__(z) |
把
s
更新成它与
z
的对称差集
|
表 1-2:集合的比较运算符,返回值是布尔类型
数学符号 | Python运算符 | 方法 | 描述 |
—— | —— | s.isdisjoint(z) |
查看
s
和
z
是否不相交(没有共同元素)
|
e
∈
S
| e in s | s.__contains__(e) |
元素
e
是否属于
s
|
S
⊆
Z
| s <= z | s.__le__(z) |
s
是否为
z
的子集
|
s.issubset(it) |
把可迭代的
it
转化为集合,然后查看 s 是否为它的子集
| ||
S
⊂
Z
| s < z | s.__lt__(z) |
s
是否为
z
的真子集
|
S
⊇
Z
| s >= z | s.__ge__(z) |
s
是否为
z
的父集
|
s.issuperset(it)
|
把可迭代的
it
转化为集合,然后查看 s 是否为它的父集
| ||
S
⊃
Z
| s > z | s.__gt__(z) |
s
是否为
z
的真父集
|
表 1-3:集合类型的其他方法
方法 | set | frozenset | 描述 |
s.add(e) | √ | × |
把元素
e
添加到
s
中
|
s.clear()
| √ | × |
移除掉
s
中的所有元素
|
s.copy() | √ | √ |
对
s
浅复制
|
s.discard(e)
| √ | × |
如果
s
里有
e
这个元素的话,把它移除
|
s.__iter__()
| √ | √ |
返回
s
的迭代器
|
s.__len__()
| √ | √ | len(s) |
s.pop()
| √ | × |
从
s
中移除一个元素并返回它的值,若
s
为空,则抛出 KeyError
异常
|
s.remove(e)
| √ | × |
从
s
中移除
e
元素,若
e
元素不存在,则抛出 KeyError 异常
|
最后
以上就是难过金针菇为你收集整理的第三章(提炼)字典和集合(三)的全部内容,希望文章能够帮你解决第三章(提炼)字典和集合(三)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复