浅析Python是如何实现集合的
作者:古明地觉 发布时间:2022-05-16 03:38:58
标签:Python,集合
楔子
有几天没有更新 Python 文章了,本次我们来聊一下 Python 的集合是怎么实现的?之前我们介绍过字典的实现原理,它底层是基于哈希表实现的,而集合也是如此。
并且字典和集合实现的哈希表是一样的,在计算哈希值、解决索引冲突等方面,两者没有任何区别。唯一的区别就是存储的 entry 不同,字典的 entry 里面包含了 key、value 和 key 的哈希值,而集合的 entry 里面只包含 key 和 key 的哈希值。
事实上,集合就类似于没有value的字典。
集合的使用场景
那么集合都有哪些用处呢?
1)去重
chars = ["a", "b", "a", "c", "c"]
print(
list(set(chars))
) # ['b', 'a', 'c']
再比如你需要监听一个队列,处理接收到的消息,但每一条消息都有一个编号,要保证具有相同编号的消息只能被处理一次,要怎么做呢?
显然集合此时就派上用场了,我们可以创建一个集合,每来一条消息,就检测它的编号是否在集合中。如果存在,则说明消息已经被处理过了,忽略掉;如果不存在,说明消息还没有被处理,那么就将它的编号添加到集合中,然后处理消息。
这里暂时不考虑消费失败等情况,我们假设每条消息都是能处理成功的。
2)判断某个序列是否包含指定的多个元素
data = ["S", "A", "T", "O", "R", "I"]
# 现在要判断 data 是否包含 "T"、"R" 和 "I"
# 如果使用列表的话
print(
"T" in data and "R" in data and "I" in data
) # True
# 显然这是比较麻烦的,于是我们可以使用集合
print(
set(data) >= {"T", "R", "I"}
) # True
同理,基于此方式,我们也可以检测一个字典是否包含指定的多个 key。
data = {
"name": "satori",
"age": 17,
"gender": "female"
}
# 判断字典是否包含 name、age、gender 三个 key
print(
data.keys() >= {"name", "age", "gender"}
) # True
# 字典的 keys 方法会返回一个 dict_keys 对象
# 该对象具备集合的性质,可以直接和集合进行运算
显然对于这种需求,有了集合就方便多了。
集合的 API
然后我们来罗列一下集合支持的 API,在使用集合的时候要做到心中有数。
# 如果要创建一个空集合,那么要使用 set()
# 写成 {} 的话,解释器会认为这是一个空字典
s = {1, 2, 3}
# 添加元素,时间复杂度是 O(1)
s.add(4)
print(s) # {1, 2, 3, 4}
# 删除指定的元素,如果元素不存在则报出 KeyError
# 时间复杂度为 O(1)
s.remove(2)
print(s) # {1, 3, 4}
# 删除指定的元素,如果元素不存在则什么也不做
# 时间复杂度为 O(1)
s.discard(666)
print(s) # {1, 3, 4}
# 随机弹出一个元素并返回
# 时间复杂度为 O(1)
print(s.pop()) # 1
print(s) # {3, 4}
# 清空一个集合
s.clear()
print(s) # set()
# 还有一些 API,但我们更推荐使用操作符的方式
# 两个集合取交集
print({1, 2} & {2, 3}) # {2}
# 两个集合取并集
print({1, 2} | {2, 3}) # {1, 2, 3}
# 两个集合取差集
# s1 - s2,返回在 s1、但不在 s2 当中的元素
print({1, 2, 3} - {2, 3, 4}) # {1}
# 两个集合取对称差集
# s1 ^ s2,返回既不在 s1、也不在 s2 当中的元素
print({1, 2, 3} ^ {2, 3, 4}) # {1, 4}
# 判断两个集合是否相等,也就是内部的元素是否完全一致
# 顺序无所谓,只比较元素是否全部相同
print({1, 2, 3} == {3, 2, 1}) # True
print({1, 2, 3} == {1, 2, 4}) # False
# 判断一个集合是否包含另一个集合的所有元素
# 假设有两个集合 s1 和 s2:
# 如果 s1 的元素都在 s2 中,那么 s2 >= s1;
# 如果 s2 的元素都在 s1 中,那么 s1 >= s2;
# 如果 s1 和元素和 s2 全部相同,那么 s1 == s2;
print({1, 2, 3} > {1, 2}) # True
print({1, 2, 3} >= {1, 2, 3}) # True
来源:https://mp.weixin.qq.com/s/ASAMuBLBbVEazyPDsdCb2A


猜你喜欢
- 问题描述在做矩阵数据的归一化处理时,遇到个报错:ValueError: operands could not be broadcast to
- Selenium一、简介selenium是一个用于Web应用自动化程序测试的工具,测试直接运行在浏览器中,就像真正的用户在操作一样selen
- 我一直是使用mysql这个数据库软件,它工作比较稳定,效率也很高。在遇到严重性能问题时,一般都有这么几种可能:1、索引没有建好;2、sql写
- 先来看看js中的Null类型表示什么?null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象,一般一个未定义的变量在初次使用
- 前言Pinia是尤雨溪强烈推荐的一款Vue状态管理工具,也被认为是下一代Vuex的替代产品。优点去除了mutations,只有 state,
- 1.前言数据展示,即数据可视化,是数据分析的第五个步骤,大部分人对图形敏感度高于数字,好的数据展示方式能让人快速发现问题或规律,找到数据背后
- 上篇文章给大家介绍了Python爬虫实现百度翻译功能过程详解Python爬虫学习之翻译小程序 感兴趣的朋友点击查看。今天给大家介
- 我使用的python版本是3.5.2今天想做个语音读取的小脚本,在网上查了一下发现python里有个pyttsx可以识别文字,打算通过pip
- 描述tan() 返回x弧度的正弦值。语法以下是 tan() 方法的语法:import mathmath.tan(x)注意:tan()是不能直
- jQuery的选择器可谓异常强大,没有什么DOM里的任何数据能逃出它的掌心,这点是我非常喜欢的,以前获取NODE要用getElementBy
- 00 小编的问题小编向我们反馈,从微信里复制出来的图片,会被微信屏蔽,无法显示我们后天采用的是百度编辑器,而且已经做了远程图片本地化,于是检
- 本文实例为大家分享了js左右轮播图的具体代码,供大家参考,具体内容如下html代码<!DOCTYPE html><html
- 对于python2.7字符串在Python2.7内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,
- 一、matplotlib库1、基本绘图命令import matplotlib.pyplot as pltplt.figure(figsize
- 当我们学习surface命令时,已经看到了三维作图的一些端倪。在matlab中我么可以调用mesh(x,y,z)函数来产生三维图像。首先,我
- 一、python中字符串转换成数字(方法1)类中进行导入:import stringstr='555'num=string.
- Python全局锁(1)全局锁导致的问题全局锁的英文简称是GIL,全称是Global Interpreter Lock(全局解释器锁),来源
- 下载安装Anaconda下载地址如下,根据所需版本下载安装过程暂略(下次在安装时添加)下载安装Pycharm下载安装Pycharm,下载对应
- 寻找含有关键字文件和删除文件夹我们往往在操作文件时,会不知道文件具体的路径。一般如果只是处理一个文件的话我们可以在文件所在的文件夹下运行py
- python循环语句求和1.for循环求和sum1 = 0for i in range(1,101):? ? if i % 2 == 0:?