Python 虚拟机集合set实现原理及源码解析

Python 虚拟机集合 set 实现原理及源码解析

什么是 set

set 是 Python 中的一种基本数据类型,用于存储无序、不重复的元素集合。set 的特点是:

  • 无序性:set 中没有元素的顺序关系。
  • 互异性:set 中的元素都是唯一的,重复的元素会被自动忽略。

set 中可以存储任意类型的数据,例如数字、字符串、元组等不可变类型,但是不能存储可变类型,例如列表、集合、字典等。在 Python 中,set 使用了哈希表来实现。

哈希表的原理

哈希表是一种基于数组的数据结构,通过散列函数将关键字映射到数组中的一个位置,从而实现快速的数据查找。哈希表的核心思想是将原始数据进行多次加工,最终生成一个哈希值,然后将哈希值作为数组下标存储原始数据。在 Python 中,内置的哈希函数 hash() 可以将大部分对象转换为整数作为哈希值。

哈希表的主要优点是查找速度快,时间复杂度为 O(1),缺点是空间利用率低,因为可能存在哈希冲突,即不同的关键字生成相同的哈希值,需要额外的措施进行处理。Python 中的哈希表使用开放地址法来解决哈希冲突,具体是通过线性探测法、二次探测法或者双重哈希法等方式进行探测,直到找到空槽位为止。

set 的实现原理

当 Python 创建一个 set 对象时,会为该对象分配一块内存空间,该空间包含了实例对象的头信息和哈希表的指针 table。哈希表的实现是通过 C 语言中的 struct _setobject 结构体实现的,该结构体定义如下:

typedef struct _setobject {
   PyObject_HEAD
   /* 数据个数 */
   Py_ssize_t size;
   /* 哈希表元素个数 */
   Py_ssize_t used;
   /* 哈希表大小 */
   Py_ssize_t fill;
   /* 哈希表指针 */
   PyObject **table;
} PySetObject;

set 对象中,size 表示实例中元素的个数,used 表示哈希表中已经分配的槽位数,fill 表示哈希表的大小,table 是一个指向指针数组的指针,指向的每个元素都指向一个 HashEntry 结构体。

typedef struct {
   Py_hash_t hash;
   PyObject *key;
} HashEntry;

HashEntry 结构体包含了两个域,hash 表示该元素的哈希值,key 表示该元素的值。

set 中的操作分为两类,一类是对 set 对象本身的操作,例如向 set 中添加或者删除元素,另一类是对 set 中元素的操作,例如判断 set 中是否包含某个元素。

set 的源码解析

创建 set 实例

当我们使用以下语法创建一个 set 实例时:

s = set([1, 2, 3])

Python 调用 set() 函数来创建 set 实例,实际上是调用了 C 函数 set_new() 来创建一个新的 set 对象。该函数主要做了以下几件事情:

  1. 分配内存空间,包括头信息和哈希表指针。
  2. 设置头信息,包括类型信息和引用计数为 0。
  3. 初始化 PySetObject 结构体的成员变量,包括 sizeusedfilltable
  4. 将数据元素插入哈希表中。

添加元素到 set 中

当我们使用以下语法将元素添加到 set 中时:

s.add(4)

Python 调用 set_add() 函数来添加元素。该函数首先会检查要添加的元素在哈希表中是否存在,如果存在则返回,否则就新建一个 HashEntry 结构体,并将元素的哈希值和指针赋值给结构体的 hashkey 成员变量,然后将结构体插入到哈希表中。

从 set 中删除元素

当我们使用以下语法将元素从 set 中删除时:

s.remove(4)

Python 调用 set_discard() 函数来删除元素。该函数首先会根据元素的哈希值在哈希表中查找该元素是否存在,如果存在则删除元素,否则什么也不做。

判断元素是否在 set 中

当我们使用以下语法判断元素是否在 set 中时:

if 4 in s:
    print("元素在 set 中")

Python 调用 set_contains() 函数来判断元素是否在 set 中。该函数首先会根据元素的哈希值在哈希表中查找该元素是否存在,如果存在则返回 True,否则返回 False

示例说明

示例 1:使用 set 存储元素

如下代码展示了如何使用 set 存储元素,包括创建 set 实例和向 set 中添加元素:

# 创建 set 实例
s = set()
# 向 set 中添加元素
s.add(1)
s.add(2)
s.add(3)
# 打印 set 中的元素
print(s)  # 输出:{1, 2, 3}

示例 2:使用 set 进行元素去重

如下代码展示了如何使用 set 对列表元素进行去重:

# 定义一个包含重复元素的列表
lst = [1, 2, 2, 3, 3, 3, 4, 5, 5, 5]
# 将列表元素转换为 set,去重后再转换回列表
lst = list(set(lst))
# 打印去重后的列表
print(lst)  # 输出:[1, 2, 3, 4, 5]

以上示例说明了 set 的两个常见用途,一个是存储元素,另一个是进行元素去重。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 虚拟机集合set实现原理及源码解析 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • Python3离线安装Requests模块问题

    针对“Python3离线安装Requests模块问题”的完整攻略,我会在以下几个方面进行详细讲解: Requests模块的介绍 Python3离线安装Requests模块的方法 示例说明 常见问题解答 Requests模块的介绍 Requests是Python中一个用于发送HTTP请求的库,可以简化HTTP请求的操作。它采用Python中自带的urllib库…

    python 2023年5月14日
    00
  • 如何使用Python实现ORM框架?

    以下是使用Python实现ORM框架的完整攻略。 ORM框架简介 ORM(Object-Relational Mapping)框架是一种将对象模型和关系数据库之间的映射技术。ORM框架可以将数据库中的映射为Python中的类,将表中的行映射为类的实例,将表中的列映射为类的属性。ORM框架可以使开发人员更加方便地操作数据库,而需要编写复杂的SQL语句。 步骤1…

    python 2023年5月12日
    00
  • Python 如何给图像分类(图像识别模型构建)

    下面是我的完整回答。 一、简介 图像分类是指在训练样本的基础上,通过构建分类模型实现对新输入图像进行分类的技术。在机器学习领域,图像分类是一类非常重要的应用场景,而Python作为一种非常流行的编程语言,也具备非常优秀的图像处理和机器学习的能力。本文将详细讲解如何使用Python进行图像分类。 二、图像分类的过程 1. 数据准备 在进行图像分类之前,首先需要…

    python 2023年5月19日
    00
  • python中列表添加元素的几种方式(+、append()、extend())

    以下是“Python中列表添加元素的几种方式(+、append()、extend())”的完整攻略。 1. 列表添加元素的几种方式 在Python中,可以使用多种方式向列表添加元素。下面介绍三种常用的方式:使用+运符、使用append()方法和使用extend()方法。 1.1 使用运算符 使用运算符可以将两个列表合并成一个新的列表。示例如下: list1 …

    python 2023年5月13日
    00
  • python dict remove数组删除(del,pop)

    下面是关于“Python字典中元素删除的两种方式——del和pop”的攻略。 Python字典 Python的字典是一种无序的键值对(Key-Value)的数据类型,可以通过键来对值进行访问。在字典中,键必须是唯一的,而值则不必。 方法一:使用del语句删除字典元素 在Python中,可以使用del语句来删除字典中的元素。最基础的用法是通过键值对中的键来删除…

    python 2023年6月5日
    00
  • python如何统计代码运行的时长

    统计Python代码的运行时长,可以使用Python内置的time模块。具体实现步骤如下: 步骤一:导入time模块 在Python脚本中,通过import time语句导入time模块。 import time 步骤二:获取代码开始执行时的时间 使用time模块的time()函数,获取代码开始执行时的时间戳。 start_time = time.time(…

    python 2023年6月2日
    00
  • Python安装与基本数据类型教程详解

    Python安装教程 1. 下载安装包 首先,从Python官方网站(https://www.python.org/downloads/)下载最新版本的Python安装包。 2. 运行安装包 下载完成之后,双击运行安装包。在安装界面中选择“Install Now”以开始安装。 3. 配置环境变量 安装完成之后,需要将Python安装路径添加到系统环境变量中。…

    python 2023年5月20日
    00
  • 用Python读取几十万行文本数据

    为了用Python读取大量文本数据,通常需要考虑以下几个方面: 选择适合的数据结构,如何优化内存使用; 操作文本文件的读取与写入; 对文本数据进行处理、分词、统计等操作。 下面是一个完整的攻略: 选择适合的数据结构 当读取大量文本数据时,需要使用适合的数据结构来提高程序的运行效率,比如使用生成器、迭代器等方式。下面为读取大文本数据的三种方式: 内存映射文件 …

    python 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部