当前位置: 首页 > news >正文

Python中的可哈希与不可哈希对象详解

文章目录

  • 1. 前置知识:哈希是什么
  • 2. 可哈希和不可哈希对象的定义
    • 2.1可哈希
    • 2.2 不可哈希
  • 3. 对象的哈希方法
    • 3.1 自定义对象的哈希方法
    • 3.2 可哈希性与等价性
    • 3.3 哈希值的用途
  • 推荐

在复习可变对象和不可变对象时,学到了这个内容


1. 前置知识:哈希是什么

哈希(Hashing)是一种将任意大小的数据转换成固定大小的数据的过程。这种转换通过哈希函数实现,它接收输入(或“消息”),并返回一个通常具有固定长度的字符串,这个字符串被称为哈希值或哈希码。哈希的主要用途包括数据的快速查找、数据完整性校验、以及安全应用中的加密技术。

哈希的关键特点是:

  • 效率高:哈希函数设计为能够快速处理大量数据。
  • 确定性:对于同一输入总是产生相同的输出。
  • 随机分布:哈希值应均匀且随机分布,减少冲突。
  • 不可逆性:理想的哈希函数使得从哈希值恢复原始输入极其困难。

2. 可哈希和不可哈希对象的定义

2.1可哈希

可哈希对象是指其生命周期内具有不变的哈希值的对象。这些对象可以作为字典的键或者集合的元素。整数、浮点数、字符串和元组都是可哈希的。

整数的哈希值

x = 10
print(hash(x))  # 输出:10的哈希值

用内置的hash()函数来获取一个整数的哈希值。

2.2 不可哈希

不可哈希对象是指内容可以更改的对象,因此哈希值也可能会变。列表和字典是典型的不可哈希对象。

列表的不可哈希性

my_list = [1, 2, 3]
try:print(hash(my_list))
except TypeError as e:print(e)  # 输出错误信息,指出列表是不可哈希的

由于列表是可变的,Python不允许对其进行哈希。所以尝试哈希列表将抛出一个TypeError。

3. 对象的哈希方法

3.1 自定义对象的哈希方法

可哈希对象需要实现__hash__()方法,该方法返回对象的哈希值。如果对象是可变的,则应返回None,表示对象不可哈希。

class Person:def __init__(self, name):self.name = namedef __hash__(self):return hash(self.name)  # 基于名字的哈希值person = Person('Alice')
print(hash(person))  # 输出:Alice的哈希值

定义了一个Person类,重写__hash__()方法使其实例可哈希。哈希函数基于人的名字来计算哈希值,根据对象的某个不变属性来提供一个一致的哈希值。

3.2 可哈希性与等价性

如果两个对象的哈希值相同,它们首先被视为可能相等,然后通过__eq__()方法进行进一步的比较来确定是否真的相等。

实现等价性

class Product:def __init__(self, id, name):self.id = idself.name = namedef __hash__(self):return hash(self.id)def __eq__(self, other):return self.id == other.idproduct1 = Product(1, 'Apple')
product2 = Product(1, 'Apple')
print(hash(product1) == hash(product2))  # 输出:True
print(product1 == product2)  # 输出:True

Product类通过id属性来定义其哈希方法和等价性检测。只要两个产品的id相同,就被认为是相等的,这说明了在自定义类中如何同时实现__hash__()和__eq__()方法来保证对象可以被正确地用于字典键或集合元素。

3.3 哈希值的用途

哈希值用于快速比较对象是否相同,是字典和集合高效性的关键。

字典中使用哈希值

my_dict = {person: 'Engineer'}
print(my_dict[person])  # 输出:'Engineer'

只有可哈希对象才可以作为字典的键

推荐

推荐我的相关专栏:

  • python 错误记录
  • python 笔记
http://www.lryc.cn/news/338569.html

相关文章:

  • 【嵌入式DIY实例】-DIY速度计
  • 1.0 Hadoop 教程
  • 【无人机/平衡车/机器人】详解STM32+MPU6050姿态解算—卡尔曼滤波+四元数法+互补滤波(文末附3个算法源码)
  • 智能水务系统:构建高效节水的城市水网
  • 【JavaEE初阶系列】——网络编程 UDP客户端/服务器 程序实现
  • 数据结构复习指导之绪论(算法的概念以及效率的度量)
  • C语言经典例题(23)
  • Gitea的简单介绍
  • Qt信号与槽
  • QQ农场-phpYeFarm添加数据教程
  • Java中创建多线程的方法
  • MT3020 任务分配
  • 【Redis】事务
  • 每日一题(leetcode238):除自身以外数组的乘积--前缀和
  • 内网通如何去除广告,内网通免广告生成器
  • 视频知识整理
  • 【2024】使用Rancher管理k8s集群和创建k8s集群
  • 生成对抗网络 – Generative Adversarial Networks | GAN
  • 基于深度学习的生活垃圾智能分类系统(微信小程序+YOLOv5+训练数据集+开题报告+中期检查+论文)
  • 软件包名生成参考
  • 八大排序算法(面试被问到)
  • SCP指令详细使用介绍
  • 《前端面试题》- JS基础 - 防抖和节流
  • RAGFlow:基于OCR和文档解析的下一代 RAG 引擎
  • 正则表达式|*+?
  • 前端开发攻略---根据音频节奏实时绘制不断变化的波形图。深入剖析如何通过代码实现音频数据的可视化。
  • 【计算机毕业设计】基于Java+SSM的实战开发项目150套(附源码+演示视频+LW)
  • STM32H7的MPU学习和应用示例
  • 964: 数细胞
  • 流程图步骤条