


下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医院科研过程管理制度
- 完善机关饭堂管理制度
- 公司门禁密码管理制度
- 大汉集团薪酬管理制度
- 单位涉案财物管理制度
- 小区绿化水泵管理制度
- 员工设备工具管理制度
- 压铸行业安全管理制度
- 计算机三级考试新思潮试题及答案
- 嵌入式软件测试方法试题及答案
- 2025年服装进货合同范本下载8篇
- 劳务纠纷案例分析:提供劳务者受害责任纠纷
- 2024年江苏省宝应县事业单位公开招聘紧缺人才37名笔试题带答案
- 保险公司保全试题及答案
- 储能项目投资合作协议书模板
- 交通过程中的大数据应用试题及答案
- 四年级下册科学教学设计-3.5《岩石、沙和黏土》教科版(含活动手册)
- 电工测量基本知识课件
- 2024危重症患儿管饲喂养护理-中华护理学会团体标准解读
- 加油赊欠合同标准文本
- 水井打井施工中的技术难点与解决措施
评论
0/150
提交评论