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视频