python唯一映射类型_Python基础:04映射类型
字典是Python語言中唯一的映射類型。一個(gè)字典對(duì)象是可變的,它是一個(gè)容器類型,能存儲(chǔ)任意個(gè)數(shù)的Python對(duì)象。字典中的數(shù)據(jù)是無序排列的。
映射類型也可被稱做哈希表,哈希表的算法是獲取鍵,對(duì)鍵執(zhí)行一個(gè)叫做哈希函數(shù)的操作,并根據(jù)計(jì)算的結(jié)果,選擇在數(shù)據(jù)結(jié)構(gòu)的某個(gè)地址中來存儲(chǔ)值。任何一個(gè)值存儲(chǔ)的地址皆取決于它的鍵。正因?yàn)檫@種隨意性,哈希表中的值是沒有順序的。哈希表一般有很好的性能,因?yàn)橛面I查詢相當(dāng)快。
一:創(chuàng)建字典
1:dict()
從Python2.2版本起,可以用工廠方法 dict() 來創(chuàng)建字典。
如果不提供參數(shù),會(huì)生成空字典。若參數(shù)是可以迭代的,如序列、迭代器,或是一個(gè)支持迭代的對(duì)象,那每個(gè)可迭代的元素必須成對(duì)出現(xiàn)。在每個(gè)值對(duì)中,第一個(gè)元素是字典的鍵、第二個(gè)元素是字典中的值。例子:
>>> fdict = dict((['x', 1], ['y', 2]))>>>fdict
{'y': 2, 'x': 1}>>> dict(zip(('x', 'y'), (1, 2)))
{'y': 2, 'x': 1}>>> dict([('xy'[i-1], i) for i in range(1,3)])
{'y': 2, 'x': 1}
如果輸入?yún)?shù)是(另)一個(gè)映射對(duì)象,比如,一個(gè)字典對(duì)象,對(duì)其調(diào)用dict()會(huì)從存在的字典里復(fù)制內(nèi)容來生成新的字典。新生成的字典是原來字典對(duì)象的淺復(fù)制版本, 它與用字典的內(nèi)建方法copy() 生成的字典對(duì)象是一樣的。但是copy()更快,所以推薦使用copy()。
從Python2.3 開始,dict()方法可以接受關(guān)鍵字參數(shù)字典:
>>> dict(x=1, y=2)
{'y': 2, 'x': 1}
2:fromkeys()
從Python2.3 版本起, 可以用內(nèi)建方法fromkeys()來創(chuàng)建一個(gè)"默認(rèn)"字典,字典中元素具有相同的值 (如果沒有給出, 默認(rèn)為None):
>>> ddict = {}.fromkeys(('x', 'y'), -1)>>>ddict
{'y': -1, 'x': -1}>>> edict = {}.fromkeys(('foo', 'bar'))>>>edict
{'foo': None, 'bar':None}
二:訪問字典
從Python2.2 開始,可以不必再用keys()方法獲取供循環(huán)使用的鍵值列表了。 可以用迭代器來輕松地訪問類序列對(duì)象(sequence-like objects),比如字典和文件。只需要用字典的名字就可以在 for 循環(huán)里遍歷字典。
>>> dict2 = {'name': 'earth', 'port': 80}>>>> for key indict2:
...print 'key=%s, value=%s' %(key, dict2[key])
...
key=name, value=earth
key=port, value=80
要得到字典中某個(gè)元素的值, 可以用字典的鍵查找操作符([ ]):
>>> dict2['name']'earth'
使用[ ]時(shí),如果在這個(gè)字典中沒有對(duì)應(yīng)的鍵,將會(huì)產(chǎn)生一個(gè)錯(cuò)誤:
>>> dict2['server']
Traceback (innermost last):
File"", line 1, in?
KeyError: server
檢查一個(gè)字典中是否有某個(gè)鍵,是用字典的 has_key()方法, 或者另一種比較好的方法就是從2.2 版本起用的,in 或 not in 操作符。
三:更新和刪除字典
1:更新
字典的鍵查找操作符([ ]),既可以用于從字典中取值,也可以用于給字典賦值。如果字典中該鍵已經(jīng)存在,則字典中該鍵對(duì)應(yīng)的值將被新值替代。如果改鍵不存在,則相當(dāng)于增加新條目:
>>> dict2['name'] = 'venus' #更新已有條目
>>> dict2['arch'] = 'sunos5' #增加新條目
2:刪除
以下是刪除字典和字典元素的例子:
del dict2['name'] ??????????? # 刪除鍵為“name”的條目
dict2.clear() ??????????????????? # 刪除dict2 中所有的條目
del dict2 ????????????????????????? #刪除整個(gè)dict2 字典
dict2.pop('name') ?????????? #刪除并返回鍵為“name”的條目
四:字典的比較
字典的比較不是很有用也不常見。比較算法按照以下的順序:
(1)比較字典長(zhǎng)度
如果字典的長(zhǎng)度不同,那么用cmp(dict1, dict2) 比較大小時(shí),如果字典 dict1 比 dict2 長(zhǎng),cmp()返回正值,如果 dict2 比 dict1 長(zhǎng),則返回負(fù)值。也就是說,字典中的鍵的個(gè)數(shù)越多,這個(gè)字典就越大。
(2)比較字典的鍵
如果兩個(gè)字典的長(zhǎng)度相同,那就按字典的鍵比較;鍵比較的順序和 keys()方法返回鍵的順序相同。這時(shí),如果兩個(gè)字典的鍵不匹配時(shí),對(duì)這兩個(gè)(不匹配的鍵)直接進(jìn)行比較。當(dāng)dict1 中第一個(gè)不同的鍵大于dict2 中第一個(gè)不同的鍵,cmp()會(huì)返回正值。
(3)比較字典的值
如果兩個(gè)字典的長(zhǎng)度相同而且它們的鍵也完全匹配,則用字典中每個(gè)相同的鍵所對(duì)應(yīng)的值進(jìn)行比較。一旦出現(xiàn)不匹配的值,就對(duì)這兩個(gè)值進(jìn)行直接比較。若dict1 比dict2 中相同的鍵所對(duì)應(yīng)的值大,cmp()會(huì)返回正值。
(4) 完全匹配
到此為止,每個(gè)字典有相同的長(zhǎng)度、相同的鍵、每個(gè)鍵也對(duì)應(yīng)相同的值,則字典完全匹配,cmp函數(shù)返回0 值。
五:字典的鍵
大多數(shù)Python對(duì)象都可以作為鍵;但它們必須是可哈希的對(duì)象。所有不可變的類型都是可哈希的,因此它們都可以做為字典的鍵。像列表和字典這樣的可變類型,由于它們不是可哈希的,所以不能作為鍵。
在執(zhí)行中字典中的鍵不允許被改變。比如創(chuàng)建了一個(gè)字典,字典中包含一個(gè)元素(一個(gè)鍵和一個(gè)值)。可能是由于某個(gè)變量的改變導(dǎo)致鍵發(fā)生了改變。這時(shí)候你如果用原來的鍵來取出字典里的數(shù)據(jù),會(huì)得到KeyError。現(xiàn)在你沒辦法從字典中獲取該值了,因?yàn)殒I本身的值發(fā)生了變化。由于上面的原因,字典中的鍵必須是可哈希的, 所以數(shù)字和字符串可以作為字典中的鍵, 但是列表和其他字典不行。
一個(gè)要說明的是問題是數(shù)字:值相等的數(shù)字表示相同的鍵。換句話來說,整型數(shù)字 1 和 浮點(diǎn)數(shù) 1.0 的哈希值是相同的,即它們是相同的鍵。
也有一些可變對(duì)象(很少)是可哈希的,它們可以做字典的鍵,但很少見。舉一個(gè)例子,一個(gè)實(shí)現(xiàn)了__hash__() 特殊方法的類。因?yàn)開_hash__()方法返回一個(gè)整數(shù),所以仍然是用不可變的值(做字典的鍵)。
數(shù)字和字符串可以被用做字典的鍵,元組雖然是不可變的,但是元組也有可能包含可變對(duì)象。所以用元組做有效的鍵,必須要加限制:元組中只包括像數(shù)字和字符串這樣的不可變參數(shù),才可以作為字典中有效的鍵。
六:映射類型相關(guān)函數(shù)
內(nèi)建函數(shù)hash()可以判斷某個(gè)對(duì)象是否可以做一個(gè)字典的鍵。將一個(gè)對(duì)象作為參數(shù)傳遞給 hash(), 會(huì)返回這個(gè)對(duì)象的哈希值。 只有這個(gè)對(duì)象是可哈希的,才可作為字典的鍵 (函數(shù)的返回值是整數(shù),不產(chǎn)生錯(cuò)誤或異常)。
如果非可哈希類型作為參數(shù)傳遞給hash()方法,會(huì)產(chǎn)生TypeError 錯(cuò)誤(因此,如果使用這樣的對(duì)象作為鍵給字典賦值時(shí)會(huì)出錯(cuò)):
>>>hash([])
Traceback (innermost last): File"", line 1, in?
TypeError: list objects are unhashable>>>
>>> dict2[{}] = 'foo'Traceback (most recent call last): File"", line 1, in?
TypeError: dict objects are unhashable
七:映射類型內(nèi)建方法
1:keys()方法,返回一個(gè)列表,包含字典中所有的鍵(的副本)。
2:values()方法,返回一個(gè)列表,包含字典中所有的值(的副本)。
3:items(),返回一個(gè)包含所有(鍵, 值)元組(的副本)的列表。這些方法在不按任何順序遍歷字典的鍵或值時(shí)很有用。
>>>dict2.keys()
['port', 'name']>>>dict2.values()
[80, 'earth']>>>dict2.items()
[('port', 80), ('name', 'earth')]
4:dict.get(key, default=None)
對(duì)字典dict中的鍵key,返回它對(duì)應(yīng)的值value,如果字典中不存在此鍵,則返回default的值,參數(shù)default的默認(rèn)值為None,所以該函數(shù)不會(huì)引發(fā)KeyError異常。該函數(shù)也不會(huì)改變字典。
5:dict.pop(key [, default])
如果字典中key鍵存在,刪除并返回dict[key],如果key 鍵不存在,但是給出了default參數(shù),則返回default。如果沒有給出default且key不存在,則引發(fā)KeyError 異常。該函數(shù)有可能改變字典。
6:update()方法可以用來將一個(gè)字典的內(nèi)容添加到另外一個(gè)字典中。字典中原有的鍵如果與新添加的鍵重復(fù),那么重復(fù)鍵所對(duì)應(yīng)的原有條目的值將被新鍵所對(duì)應(yīng)的值所覆蓋。原來不存在的條目則被添加到字典中。
7:clear()方法可以用來刪除字典中的所有的條目。
>>> dict2= {'host':'earth', 'port':80}>>> dict3= {'host':'venus', 'server':'http'}>>>dict2.update(dict3)>>>dict2
{'server': 'http', 'port': 80, 'host': 'venus'}>>>dict3.clear()>>>dict3
{}
8:copy()方法返回一個(gè)字典的副本。注意這只是淺復(fù)制。
9:setdefault(key [,default])是自2.0才有的內(nèi)建方法, 使得代碼更加簡(jiǎn)潔。它實(shí)現(xiàn)了常用的語法:如果字典中key存在,則不改變字典,直接返回它的值。如果所找的key在字典中不存在,則給這個(gè)鍵賦default并返回default,default默認(rèn)為None。
>>> myDict = {'host': 'earth', 'port': 80}>>> myDict.setdefault('port', 8080)80
>>> myDict.setdefault('prot', 'tcp')'tcp'
>>>myDict.items()
[('prot', 'tcp'), ('host', 'earth'), ('port', 80)]
10:因keys(),items(), 和 values()方法的返回值都是列表。數(shù)據(jù)集如果很大會(huì)導(dǎo)致很難處理,因此iteritems(), iterkeys(), 和itervalues() 方法被添加到 Python2.2 中。這些函數(shù)與返回列表的對(duì)應(yīng)方法相似,只是它們返回惰性賦值的迭代器,所以節(jié)省內(nèi)存。
八:其他
要避免使用內(nèi)建對(duì)象名字作為變量的標(biāo)識(shí)符。不要用 dict, list, file, bool, str, input, len 這樣的內(nèi)建類型為變量命名。
>>> print 'host %(name)s is runningon port %(port)d' %dict2
host venusis running on port 6969
上面的print語句展示了另一種使用字符串格式符( %)的方法。用字典參數(shù)可以簡(jiǎn)化print 語句,因?yàn)檫@樣做你只須用到一次該字典的名字,而不用在每個(gè)元素出現(xiàn)的時(shí)候都用元組參數(shù)表示。
總結(jié)
以上是生活随笔為你收集整理的python唯一映射类型_Python基础:04映射类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序观点下的线性代数
- 下一篇: 清华计算机系上热搜!近9成优秀毕业生放弃