Python set和frozenset集合操作(附带两者区别)
Python set集合
set 集合有如下两个特征:- set 不记录元素的添加顺序。
- 元素不允许重复。
在交互式解释器中输入
[e for e in dir(set) if not e.startswith('_')] 来查看 set 集合的全部方法,可以看到如下输出结果:
>>> [e for e in dir(set) if not e.startswith('_')]
['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
remove() 与 discard() 方法都用于删除集合中的元素,但区别在于,如果集合中不包含被删除的元素,remove() 方法会报出 KeyError 异常,而 discard() 方法则什么也不做。
下面程序示范了 set 集合的方法的用法:
# 使用花括号构建set集合
c = {'白骨精'}
# 添加元素
c.add("孙悟空")
c.add(6)
print("c集合的元素个数为:" , len(c)) # 输出3
# 删除指定元素
c.remove(6)
print("c集合的元素个数为:" , len(c)) # 输出2
# 判断是否包含指定字符串
print("c集合是否包含'孙悟空'字符串:" , ("孙悟空" in c)) # 输出True
c.add("轻量级Java EE企业应用实战")
print("c集合的元素:" , c)
# 使用set()函数(构造器)来创建set集合
books = set()
books.add("轻量级Java EE企业应用实战")
books.add("疯狂Java讲义")
print("books集合的元素:" , books)
# issubset()方法判断是否为子集合
print("books集合是否为c的子集合?", books.issubset(c)) # 输出False
# issubset()方法与<=运算符效果相同
print("books集合是否为c的子集合?", (books <= c)) # 输出False
# issuperset()方法判断是否为父集合
# issubset和issuperset其实就是倒过来判断
print("c集合是否完全包含books集合?", c.issuperset(books)) # 输出False
# issuperset()方法与>=运算符效果相同
print("c集合是否完全包含books集合?", (c >= books)) # 输出False
# 用c集合减去books集合里的元素,不改变c集合本身
result1 = c - books
print(result1)
# difference()方法也是对集合做减法,与用-执行运算的效果完全一样
result2 = c.difference(books)
print(result2)
# 用c集合减去books集合里的元素,改变c集合本身
c.difference_update(books)
print("c集合的元素:" , c)
# 删除c集合里的所有元素
c.clear()
print("c集合的元素:" , c)
# 直接创建包含元素的集合
d = {"疯狂Java讲义", '疯狂Python讲义', '疯狂Kotlin讲义'}
print("d集合的元素:" , d)
# 计算两个集合的交集,不改变d集合本身
inter1 = d & books
print(inter1)
# intersection()方法也是获取两个集合的交集,与用&执行运算的效果完全一样
inter2 = d.intersection(books)
print(inter2)
# 计算两个集合的交集,改变d集合本身
d.intersection_update(books)
print("d集合的元素:" , d)
# 将range对象包装成set集合
e = set(range(5))
f = set(range(3, 7))
print("e集合的元素:" , e)
print("f集合的元素:" , f)
# 对两个集合执行异或运算
xor = e ^ f
print('e和f执行xor的结果:', xor)
# 计算两个集合的并集,不改变e集合本身
un = e.union(f)
print('e和f执行并集的结果:', un)
# 计算两个集合的并集,改变e集合本身
e.update(f)
print('e集合的元素:', e)
上面程序基本示范了 set 集合中所有方法的用法。不仅如此,该程序还示范了 set 集合支持的如下几个运算符:
- <=:相当于调用 issubset() 方法,判断前面的 set 集合是否为后面的 set 集合的子集合。
- >=:相当于调用 issuperset() 方法,判断前面的 set 集合是否为后面的 set 集合的父集合。
- -:相当于调用 difference() 方法,用前面的 set 集合减去后面的 set 集合的元素。
- &:相当于调用 intersection() 方法,用于获取两个 set 集舍的交集。
- ^:计算两个集合异或的结果,就是用两个集合的并集减去交集的元素。
此外,由于 set 集合本身是可变的,因此它除了提供 add()、remove()、discard() 方法来操作单个元素,还支持进行集合运算来改变集合内的元素。因此,它的集合运算方法都有两个版本:
- 交集运算:intersection() 和 intersection_update(),前者不改变集合本身,而是返回两个集合的交集;后者会通过交集运算改变第一个集合。
- 并集运算:union() 和 update(),前者不改变集合本身,而是返回两个集合的并集;后者会通过并集运算改变第一个集合。
- 减法运算:difference() 和 difference_update(),前者不改变集合本身,而是返回两个集合做咸法的结果;后者改变第一个集合。
Python frozenset集合
frozenset 是 set 的不可变版本,因此 set 集合中所有能改变集合本身的方法(如 add、remove、discard、xxx_update 等),frozenset 都不支持;set 集合中不改变集合本身的方法,fronzenset 都支持。在交互式解释器中输入
[e for e in dir(frozenset) if not e.startswith('_')] 命令来查看 frozenset 集合的全部方法,可以看到如下输出结果:
[e for e in dir(frozenset) if not e.startswith('_')]
['copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
frozenset 的作用主要有两点:
- 当集合元素不需要改变时,使用 frozenset 代替 set 更安全。
- 当某些 API 需要不可变对象时,必须用 frozenset 代替set。比如 dict 的 key 必须是不可变对象,因此只能用 frozenset;再比如 set 本身的集合元素必须是不可变的,因此 set 不能包含 set,set 只能包含 frozenset。
如下程序示范了在 set 中添加 frozenset:
s = set()
frozen_s = frozenset('Kotlin')
# 为set集合添加frozenset
s.add(frozen_s)
print('s集合的元素:', s)
sub_s = {'Python'}
# 为set集合添加普通set集合,程序报错
s.add(sub_s)
上面程序中第 4 行代码为 set 添加 frozenset,程序完全没有问题,这样 set 中就包括一个 frozenset 子集合;第 8 行代码试图向 set 中添加普通 set,程序会报出 TypeError 异常。运行上面代码,可以看到如下输出结果:
s集合的元素: {frozenset({'t', 'o', 'i', 'K', 'l', 'n'})}
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 8, in <module>
s.add(sub_s)
TypeError: unhashable type: 'set'
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频