下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
python中字典的键是唯⼀的吗_Python中字典的key都可以是什么作者:Inotime来源:CSDN答:⼀个对象能不能作为字典的key,就取决于其有没有__hash__⽅法。所以所有python⾃带类型中,除了list、dict、set和内部⾄少带有上述三种类型之⼀的tuple之外,其余的对象都能当key。⽐如数值/字符串/完全不可变的元祖/函数(内建或⾃定义)/类(内建或⾃定义)/⽅法/包等等你能拿出⼿的,不过有的实际意义不⾼。还有数值型要注意,因为两个不同的相等数字可以有相同的哈希值,⽐如1和1.0。解释:代码版本:3.6.3;⽂档版本:3.6.6Unlikesequences,whichareindexedbyarangeofnumbers,dictionariesareindexedbykeys,whichcanbeanyimmutabletype;stringsandnumberscanalwaysbekeys.Tuplescanbeusedaskeysiftheycontainonlystrings,numbers,ortuples;ifatuplecontainsanymutableobjecteitherdirectlyorindirectly,itcannotbeusedasakey.Youcan’tuselistsaskeys,sincelistscanbemodifiedinplaceusingindexassignments,sliceassignments,ormethodslikeappend()andextend().字典的键可以是任意不可变类型,需要注意的是tuple元组作为键时,其中不能以任何⽅式包含可变对象。那。。到底什么样的是不可变类型呢?不可能给对象专门标注⼀个属性是可变类型还是不可变类型啊,这没有任何其他意义,⼀定是通过其他途径实现的。把list当做键试⼀下a=[1,2,3]d={a:a}#第⼆⾏报错:#TypeError:unhashabletype:'list'报错说list类型是不可哈希的,噢,原来是靠能不能hash来判断的,另外⽂档下⾯接着说同⼀字典中每个键都是唯⼀的,正好每个对象的哈希值也是唯⼀的,对应的很好。Itisbesttothinkofadictionaryasanunorderedsetofkey:valuepairs,withtherequirementthatthekeysareunique(withinonedictionary).查看源代码可以看到object对象是定义了__hash__⽅法的,⽽list、set和dict都把__hash__赋值为None了#部分源码classobject:"""Themostbasetype"""def__hash__(self,*args,**kwargs):#realsignatureunknown"""Returnhash(self)."""passclasslist(object):__hash__=Noneclassset(object):
__hash__=Noneclassdict(object):__hash__=None那这样的话。。。我给他加⼀个hash不就能当字典的key了,key不就是可变的了。注意:此处只是我跟着想法随便试,真的应⽤场景不要⽤可变类型作为字典的key。classMyList(list):"""⽐普通的list多⼀个__hash__⽅法"""def__hash__(self):#不能返回hash(self)#hash(self)会调⽤self的本⽅法,再调⽤回去,那就没完了(RecursionError)#⽤的时候要注意实例中⾄少有⼀个元素,不然0怎么取(IndexError)returnhash(self[0])l1=MyList([1,2])#print(l1)->[1,2]d={l1:'Can?'}print(d)#-->{[1,2]:'Can?'}l1.append(3)print(d)#{[1,2,3]:'Can?'}print(d[l1])#-->Can?到这⾥就可以肯定的说,⼀个对象能不能作为字典的key,就取决于其有没有__hash__⽅法。所以所有python⾃带类型中,⽬前我已知的除了list、dict、set和内部带有以上三种类型的tuple之外,其余的对象都能当key。⽽我们⾃⼰定义的类,⼀般情况下都直接间接的和object有关,都带有__hash__⽅法。另外我想到,既然字典的键是唯⼀的,⽽哈希值也是唯⼀的,这么巧,键的唯⼀性不会就是⽤哈希值来确定的吧?我上⼀个例⼦中__hash__⽅法返回的是0号元素的哈希值,那我直接⽤相同哈希值的对象是不是就能改变那本来不属于它的字典值呢?classMyList(list):def__hash__(self):returnhash(self[0])l1=MyList([1,2])#print(l1)->[1,2]d={}d[l1]=l1print(d)#{[1,2]:[1,2]}d[1]=1print(d)#{[1,2]:[1,2],1:1}竟然没有改成功⽽是新添加了⼀个键值对,可self[0]就是1啊,哈希值⼀样啊,怎么会不⼀样呢?难道要键的值⼀样才能判断是同⼀个键吗?重写__eq__⽅法试⼀下。classMyList(list):def__hash__(self):
returnhash(self[0])def__eq__(self,other):returnself[0]==otherl1=MyList([1,2])#print(l1)->[1,2]d={}d[l1]=l1print(d)#{[1,2]:[1,2]}d[1]=1print(d)#{[1,2]:1}这回成功了,那就是__hash__返回值相等,且eq判断也相等,才会被认为是同⼀个键。那这两个先判断哪个呢?加代码试⼀下classMyList(list):def__hash__(self):print('hashisrun')returnhash(self[0])def__eq__(self,other):print('eqisrun')returnself[0]==otherl1=MyList([1,2])#print(l1)->[1,2]d={}d[1]=1d[l1]='l1'print(d)#结果:#hashisrun#eqisrun#{1:'l1'}__hash__先执⾏,另外字典在内存中存储数据的位置和键的hash也是有关的,逻辑上也像印证。先计算hash,找到相对应的那⽚内存空间,⾥⾯没有值的话就直接写⼊,对于字典来说就是新增键值对;如果⾥⾯已经有值了,那就判断新来的键和原来的那⾥的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 防雷设施安装维护合同三篇
- 化妆品行业保安工作总结
- 儿童游乐设施设计美工工作总结
- 林业行业美工的森林保护
- 风险防范工作总结
- 【八年级下册地理粤教版】第8章 珠江三角洲 单元测试
- 本科生毕业论文答辩记录表
- 2025届扬州市高三语文(上)1月质量调研试卷及答案解析
- 创新成果知识产权合同(2篇)
- DB33T 2188.4-2019 大型赛会志愿服务岗位规范 第4部分:礼宾接待志愿服务
- 养老服务中心装饰装修工程施工方案
- 落地式脚手架监理实施细则
- 上海市金山区2022-2023学年中考一模英语试题含答案
- 节水灌溉供水工程初步设计报告
- 【期末试题】河西区2018-2019学年度第一学期六年级数学期末试题
- 2022年总经理年会发言稿致辞二
- 警综平台运行管理制度
- 立法学完整版教学课件全套ppt教程
- 简约中国风水墨山水工作总结通用PPT模板
- 矿山测量课程设计
- 药厂生产车间现场管理-PPT课件
评论
0/150
提交评论