更多内容,欢迎关注微信公众号: tmac_lover

上一篇介绍python中字典和集中时,提到,字典和集合的优势在于增删改查非常高效,而高效的原因就在于,python中字典和集合这两个数据结构是基于散列表 来实现的。散列表也叫哈希表,英文是hashtable。是一种非常高效的基础数据结构,今天我们介绍一下散列表的原理,了解了原理之后,就会很容易理解为什么 字典和集合的增删改查如此高效。

什么是散列表

散列表听上去好像很玄乎,但是实际上在我们的生活中却非常的常见。举个很简单的例子,我们读大学的时候,辅导员老师那里的excel表里有每个学生的信息,如果我们想要查找某一个学生的信息,使用什么方法最迅速呢?

一种很容易想到的方法是打开excel,然后从第一行开始一行一行的看,直接看到我们想要找的那个学生的那一行为止,可想而知,如果有5000个学生,很不巧这名 学生刚好在excel表的最后一行,是不是要耗很长时间才能找到。这种方法有点类似于列表,查找的时间复杂度为O(n)。

还有另外的方法,因为每个学生都有学号,并且学号是连续的,如果我们存储的时候,直接按学号从小到大的顺序,从第一行开始存,查找的时候,只要知道学生的 身份证号,是不是就能很快速的定位到该名学生在excel表格里的第几行,然后就可以直接拿到学生的信息。使用这种方式,只需要经过一次计算,就能确定学生信 息的位置,而这个计算的时间是相对固定的。这就是典型的一种散列表的思想,它查找的时间复杂度是O(1)。这个计算偏移的方法,就相当于散列函数。这里学生 的学号就是散列表中的键(key)。 用图表示就像下面这样:

我们只需要设计一个散列函数,然后利用这个散列函数,根据学生的学号就可以计算出每个学生信息在excel表里的存储位置。这样就可以实现快速的增删改查,效 率非常的高。

以上就是散列表所包含的非常基础的思想。当然实际的散列表的实现,还要考虑的因素有很多,比如: hash函数的设计,这个函数要求对同样的输入,输出一定要相同,而对于不同的输入,输出尽量减少冲突 如果出现散列冲突(即两个Key经过散列函数之后输出相同),使用什么方式解决散列冲突 * 装载因子的设置,因为散列表是可以增加元素的,为了避免空间满时减加元素时元素搬移太耗时,需要为散列表预留一些空间,当表中元素达到某个域值时,对整 个散列表进行整体搬移和扩容,这个域值就是装载因子

如果想更深入的了解散列表,可以自行查阅一些资料,在这里,我们只需要了解散列表的实现原理,以及为什么散列表的增删改查效率如此之高就可以了。

为什么字典和集合是无序的

了解了上面所说的散列表的基本原理之后,我们知道,散列表中元素的实际存储位置是由所设计的散列函数对键(key)进行运算后得出的。上面所举的学号的例子 比较特殊,使用的散列函数相当于只是对学号数字取了一个偏移来得到学生信息存储位置。而实际上大多数的散列函数在对键进行计算后,得到的存储位置是随机的, 并不连续,所以元素的存储位置也就不一定和输入的顺序相同。

列表可以做为键(key)吗

讨论这个问题前,我们需要知道字典的键必须要求是可以散列的,而一个可散列的对象必须满足以下要求:

  • 支持hash()函数,并且通过hash()方法所得到的散列值是不变的
  • 支持通过eq()方法检测相等性
  • 若a==b为真,则hash(a) == hask(b)也必须为真

通过下面代码测试一下:

l = [1,2,3,4]
print(hash(l))

运行会报如下错误:

Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

实际上,list并没有实现hash()这个魔法函数,因为只有不可变对象,才可以进行hash, 像字符串,字典这种都属于不可变对象,而集合,列表,字典都 属于可变对象,所以它们无法作为字典的key。

散列表的设计与实现_python基础之字典与集合实现相关推荐

  1. python集合属性方法运算_Python基础__字典、集合、运算符

    之前讨论的字符串.列表.元组都是有序对象,本节则重点讨论无序对象:字典与集合. 一.字典 列表是Python中的有序集合,列表中的序指的是列表中的元素与自然数集形成了一个一一对应的关系.例如L=['I ...

  2. 散列表的设计与实现_散列表:如何实现word编辑器的拼写检查?

    Word文档编辑器大家应该经常使用吧,大家有没有留意到它编辑功能,当我们输入一个错误的单词时,单词单面就会标红提示"拼写 错误",这个功能是怎么实现的呢?其实啊,它是通过散列表实现 ...

  3. 数据结构课设(散列表的设计与实现---电话号码查找系统)

    一.要求: [问题描述] 设计散列表实现电话号码查找系统. [基本要求] 1) 设每个记录有下列数据项:电话号码.用户名.地址:2) 从键盘输入各记录,分别以电话号码和用户名为关键字建立散列表:3)  ...

  4. 考研数据结构之查找(9.8)——练习题之使用散列函数H(k)= 3k mod 11并采用链地址法处理冲突并构造散列表及设计散列表的完整算法(C表示)

    题目 使用散列函数: H(k)= 3*k mod 11 并采用链地址法处理冲突.试对关键字序列(22, 41, 53, 46, 30, 13, 01, 67)构造散列表,求等概率情况下查找成功的平均查 ...

  5. python列表可以放不同类型_python基础篇数据类型之二——列表(List)

    好喽! 迟到的更新来了 ! 上回分享了数据类型中的一位重要成员--'字符串' 别看它弱不禁风,绝大部分场景都能遇到它,例如人口普查表格内录入的信息,word文档内容,网页登陆框和密码输入框等等都会有它 ...

  6. python集合和字典的区别_Python中的字典和集合

    导语:本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流. 本文重点: 1.掌握常见的字典创建,查询,判别方法: 2.了解字典中的 ...

  7. 刻意练习:Python基础 -- Task06. 字典与集合

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  8. python字典和集合对象可以进行索引操作_Python中的字典跟集合整理笔记

    泛映射类型 映射类型:不仅仅是dict,标准库里的所有映射类型都是利用dict来实现的,因此它们有个共同的限制,即只有可散列的数据类型才能用做这些映射的键.(只有键有这个需求,值并不需要必须是可散列的 ...

  9. python字典与顺序有关吗_python – 为什么在字典和集合中的顺序是任意的?

    顺序不是任意的,而是取决于字典或集合的插入和删除历史,以及特定的Python实现.对于这个答案的其余部分,对于'dictionary',你还可以读取'set';集合被实现为仅具有键且没有值的字典. 键 ...

最新文章

  1. 最新的GAN方法——PGGAN揭秘
  2. wince中对ini文件的操作
  3. 电信笔试c语言编程,华工电信院电子与通信工程 923复试面试,笔试考什么?复试真题...
  4. 项目笔记:2017年(SSM架构)
  5. Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
  6. 用友u8服务器优化,用友U8v10.1运行速度慢的问题及解决方法
  7. JAVA写的文件分割与文件合并程序
  8. 微软亚研院华刚对科研的见解
  9. substring substr slice 区别
  10. Android,iOS打开手机QQ与指定用户聊天界面
  11. scrapy 官方文档(入门必备)
  12. HS系列USB数据采集卡,及高速多通道数据分析软件详解
  13. 《全民学乒乓》学习笔记
  14. js 安卓和ios的一些奇奇怪怪的注意点
  15. Correct the classpath of your application so that it contains compatible versions of the classes com
  16. Android利用自定义View实现简单的足球战术板
  17. 三菱plc恒压供水程序+威纶触摸屏程序 以控制水泵一用一备、一拖二、一拖三、一拖四、一拖四带小泵恒压功能
  18. Autosar代码包初识 3 - 创建RH850的GreenHills工程编译Autosar Demo工程
  19. elasticsearch-java客户端测试
  20. Mac是不是基于Linux系统开发?

热门文章

  1. python3 编写守护进程程序思路
  2. 添加RichEdit控件导致MFC对话框程序无法执行的解决方法
  3. Android开发RSS阅读器
  4. 内核网络中的GRO、RFS、RPS技术介绍和调优
  5. java 类之间数据传递_java类之间数据传递问题
  6. oracle中表空间创建,Oracle 如何创建表空间
  7. java system.runfinalization()_Android中缓存理解(一)
  8. freeswitch 按键采集_《FreeSWITCH 1.2》:支持页面呼叫控制
  9. java中文转拼音 多音字_java使用jpinyin汉语转拼音(支持多音字)
  10. linux 查找 jdk 安装路径