深入理解Python中字典的鍵的使用
字典的鍵
字典中的值沒有任何限制, 可以是任意Python對(duì)象,即從標(biāo)準(zhǔn)對(duì)象到用戶自定義對(duì)象皆可,但是字典中的鍵是有類型限制的。
(1)不允許一個(gè)鍵對(duì)應(yīng)多個(gè)值
必須明確一條原則:每個(gè)鍵只能對(duì)應(yīng)一個(gè)項(xiàng)。也就是說(shuō):一鍵對(duì)應(yīng)多個(gè)值是不允許的(像列表、元組和其他字典這樣的容器對(duì)象是可以的)。 當(dāng)有鍵發(fā)生沖突(即字典鍵重復(fù)賦值),取最后(最近)的賦值。Python并不會(huì)因字典中的鍵存在沖突而產(chǎn)生一個(gè)錯(cuò)誤,它不會(huì)檢查鍵的沖突是因?yàn)槿绻孢@樣做的話,在每個(gè)鍵-值對(duì)賦值的時(shí)候都會(huì)做檢查,這將會(huì)占用一定量的內(nèi)存。
>>> dict1 = {'foo':789, 'foo': 'xyz'} >>> dict1 {'foo': 'xyz'} >>> dict1['foo'] = 123 >>> dict1 {'foo': 123}
(2)鍵必須是可哈希的
大多數(shù)Python對(duì)象可以作為鍵,但它們必須是可哈希的對(duì)象。像列表和字典這樣的可變類型,由于它們不是可哈希的,所以不能作為鍵。
所有不可變的類型都是可哈希的,因此它們都可以做為字典的鍵。要說(shuō)明的是:值相等的數(shù)字表示相同的鍵,即整型數(shù)字1和浮點(diǎn)數(shù)1.0的哈希值是相同的,它們是相同的鍵。
同時(shí),也有一些可變對(duì)象(很少)是可哈希的,它們可以做字典的鍵,但很少見。舉一個(gè)例子,一個(gè)實(shí)現(xiàn)了__hash__() 特殊方法的類。因?yàn)開_hash__()方法返回一個(gè)整數(shù),所以仍然是用不可變的值(做字典的鍵)。
為什么鍵必須是可哈希的?解釋器調(diào)用哈希函數(shù),根據(jù)字典中鍵的值來(lái)計(jì)算存儲(chǔ)你的數(shù)據(jù)的位置。如果鍵是可變對(duì)象,它的值可改變。如果鍵發(fā)生變化,哈希函數(shù)會(huì)映射到不同的地址來(lái)存儲(chǔ)數(shù)據(jù)。如果這樣的情況發(fā)生,哈希函數(shù)就不可能可靠地存儲(chǔ)或獲取相關(guān)的數(shù)據(jù)。選擇可哈希的鍵的原因就是因?yàn)樗鼈兊闹挡荒芨淖儭?br />
數(shù)字和字符串可以被用做字典的鍵,元組是不可變的但也可能不是一成不變的,因此用元組做有效的鍵必須要加限制:若元
組中只包括像數(shù)字和字符串這樣的不可變參數(shù),才可以作為字典中有效的鍵。
示例:
# vi userpw.py
#!/usr/bin/env python
db = {} def newuser(): prompt= 'please regist your name: ' while True: name = raw_input(prompt) if db.has_key(name): prompt = 'name taken,try another: ' continue else: break pwd = raw_input('passswd: ') db[name] = pwd print 'Newuser [%s] has added successfully!' %name def olduser(): name = raw_input('login: ') pwd = raw_input('passwd: ') passwd = db.get(name) if passwd == pwd: print 'welcome back',name else: print 'login incorrect!' def showmenu(): prompt = """ (N)ew User Login (E)xisting User Login (Q)uit Enter choice: """ while True: try: choice = raw_input(prompt).strip()[0].lower() print '\nYou picked: [%s]' % choice if choice not in 'neq': print 'invalid option,please try again' if choice == 'n': newuser() if choice == 'e': olduser() if choice == 'q': break except(EOFError,KeyboardInterrupt): print 'invalid option,please try again' if __name__ == '__main__': showmenu()
相關(guān)文章
python3 實(shí)現(xiàn)驗(yàn)證碼圖片切割的方法
今天小編就為大家分享一篇python3 實(shí)現(xiàn)驗(yàn)證碼圖片切割的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12python程序快速縮進(jìn)多行代碼方法總結(jié)
在本篇文章里小編給大家整理了關(guān)于python程序如何快速縮進(jìn)多行代碼的相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-06-06Python正則表達(dá)式實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能示例
這篇文章主要介紹了Python正則表達(dá)式實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能,涉及Python正則判定及數(shù)值計(jì)算相關(guān)操作技巧,需要的朋友可以參考下2019-05-05python shapely.geometry.polygon任意兩個(gè)四邊形的IOU計(jì)算實(shí)例
這篇文章主要介紹了python shapely.geometry.polygon任意兩個(gè)四邊形的IOU計(jì)算實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04tensorflow使用freeze_graph.py將ckpt轉(zhuǎn)為pb文件的方法
這篇文章主要介紹了tensorflow使用freeze_graph.py將ckpt轉(zhuǎn)為pb文件的方法,需要的朋友可以參考下2020-04-04python socket 超時(shí)設(shè)置 errno 10054
這篇文章主要介紹了python 遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接 socket 超時(shí)設(shè)置 errno 10054 ,需要的朋友可以參考下2014-07-07