鍍金池/ 教程/ Python/ 字典(1)
標(biāo)準(zhǔn)庫 (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫 (6)
標(biāo)準(zhǔn)庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯(cuò)誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個(gè)簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯(cuò)誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實(shí)戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語句(1)
數(shù)和四則運(yùn)算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級
字符串(3)
為計(jì)算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯(cuò)誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫 (2)
列表(2)
元組

字典(1)

字典,這個(gè)東西你現(xiàn)在還用嗎?隨著網(wǎng)絡(luò)的發(fā)展,用的人越來越少了。不少人習(xí)慣于在網(wǎng)上搜索,不僅有 web 版,乃至于已經(jīng)有手機(jī)版的各種字典了。我在上小學(xué)的時(shí)候曾經(jīng)用過一本小小的《新華字典》,記得是拾了不少廢品,然后換錢,最終花費(fèi)了 1.01 元人民幣買的。

《新華字典》是中國第一部現(xiàn)代漢語字典。最早的名字叫《伍記小字典》,但未能編纂完成。自 1953 年,開始重編,其凡例完全采用《伍記小字典》。從 1953 年開始出版,經(jīng)過反復(fù)修訂,但是以 1957 年商務(wù)印書館出版的《新華字典》作為第一版。原由新華辭書社編寫,1956 年并入中科院語言研究所(現(xiàn)中國社科院語言研究所)詞典編輯室。新華字典由商務(wù)印書館出版。歷經(jīng)幾代上百名專家學(xué)者 10 余次大規(guī)模的修訂,重印 200 多次。成為迄今為止世界出版史上最高發(fā)行量的字典。

這里講到字典,不是為了回憶青蔥歲月。而是提醒看官想想我們?nèi)绾问褂米值洌合炔樗饕ú还苁瞧匆暨€是偏旁查字),然后通過索引找到相應(yīng)內(nèi)容。不用從頭開始一頁一頁地找。

這種方法能夠快捷的找到目標(biāo)。

正是基于這種需要,Python 中有了一種叫做 dictionary 的數(shù)據(jù)類型,翻譯過來就是“字典”,用 dict 表示。

假設(shè)一種需要,要存儲城市和電話區(qū)號,蘇州的區(qū)號是 0512,唐山的是 0315,北京的是 011,上海的是 012。用前面已經(jīng)學(xué)習(xí)過的知識,可以這么來做:

>>> citys = ["suzhou", "tangshan", "beijing", "shanghai"]
>>> city_codes = ["0512", "0315", "011", "012"]

用一個(gè)列表來存儲城市名稱,然后用另外一個(gè)列表,一一對應(yīng)地保存區(qū)號。假如要輸出蘇州的區(qū)號,可以這么做:

>>> print "{} : {}".format(citys[0], city_codes[0])
suzhou : 0512

請?zhí)貏e注意,我在 city_codes 中,表示區(qū)號的元素沒有用整數(shù)型,而是使用了字符串類型,你知道為什么嗎? 如果用整數(shù),就是這樣的。

suzhou_code = 0512 print suzhou_code 330

怎么會這樣?原來在 Python 中,如果按照上面那樣做,0512 并沒有被認(rèn)為是一個(gè)八進(jìn)制的數(shù),用 print 打印的時(shí)候,將它轉(zhuǎn)換為了十進(jìn)制輸出。關(guān)于進(jìn)制轉(zhuǎn)換問題,看官可以網(wǎng)上搜索一下有關(guān)資料。此處不詳述。一般是用幾個(gè)內(nèi)建函數(shù)實(shí)現(xiàn):int(), bin(), oct(), hex()

這樣來看,用兩個(gè)列表分別來存儲城市和區(qū)號,似乎能夠解決問題。但是,這不是最好的選擇,至少在 Python 里面。因?yàn)?Python 還提供了另外一種方案,那就是字典(dict)。

創(chuàng)建 dict

方法 1:

創(chuàng)建一個(gè)空的 dict,這個(gè)空 dict,可以在以后向里面加?xùn)|西用。

>>> mydict = {}
>>> mydict
{}

不要小看“空”,“色即是空,空即是色”,在編程中,“空”是很重要。一般帶“空”字的人都很有名,比如孫悟空,哦。好像他應(yīng)該是猴、或者是神。舉一個(gè)人的名字,帶“空”字,你懂得。

創(chuàng)建有內(nèi)容的 dict。

>>> person = {"name":"qiwsir","site":"qiwsir.github.io","language":"python"}
>>> person
{'name': 'qiwsir', 'language': 'python', 'site': 'qiwsir.github.io'}

"name":"qiwsir",有一個(gè)優(yōu)雅的名字:鍵值對。前面的 name 叫做鍵(key),后面的 qiwsir 是前面的鍵所對應(yīng)的值(value)。在一個(gè) dict 中,鍵是唯一的,不能重復(fù)。值則是對應(yīng)于鍵,值可以重復(fù)。鍵值之間用(:)英文的分號,每一對鍵值之間用英文的逗號(,)隔開。

>>> person['name2']="qiwsir"    #這是一種向 dict 中增加鍵值對的方法
>>> person
{'name2': 'qiwsir', 'name': 'qiwsir', 'language': 'Python', 'site': 'qiwsir.github.io'}

用這樣的方法可以向一個(gè) dict 類型的數(shù)據(jù)中增加“鍵值對”,也可以說是增加數(shù)值。那么,增加了值之后,那個(gè)字典還是原來的嗎?也就是也要同樣探討一下,字典是否能原地修改?(列表可以,所以列表是可變的;字符串和元組都不行,所以它們是不可變的。)

>>> ad = {}
>>> id(ad)
3072770636L
>>> ad["name"] = "qiwsir"
>>> ad
{'name': 'qiwsir'}
>>> id(ad)
3072770636L

實(shí)驗(yàn)表明,字典可以原地修改,即它是可變的。

方法 2:

利用元組在建構(gòu)字典,方法如下:

>>> name = (["first","Google"],["second","Yahoo"])      
>>> website = dict(name)
>>> website
{'second': 'Yahoo', 'first': 'Google'}

或者用這樣的方法:

>>> ad = dict(name="qiwsir", age=42)
>>> ad
{'age': 42, 'name': 'qiwsir'}

方法 3:

這個(gè)方法,跟上面的不同在于使用 fromkeys

>>> website = {}.fromkeys(("third","forth"),"facebook")
>>> website
{'forth': 'facebook', 'third': 'facebook'}

需要提醒的是,這種方法是重新建立一個(gè) dict。

需要提醒注意的是,在字典中的“鍵”,必須是不可變的數(shù)據(jù)類型;“值”可以是任意數(shù)據(jù)類型。

>>> dd = {(1,2):1}
>>> dd
{(1, 2): 1}
>>> dd = {[1,2]:1}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

訪問 dict 的值

dict 數(shù)據(jù)類型是以鍵值對的形式存儲數(shù)據(jù)的,所以,只要知道鍵,就能得到值。這本質(zhì)上就是一種映射關(guān)系。

映射,就好比“物體”和“影子”的關(guān)系,“形影相吊”,兩者之間是映射關(guān)系。此外,映射也是一個(gè)嚴(yán)格數(shù)學(xué)概念:A 是非空集合,A 到 B 的映射是指:A 中每個(gè)元素都對應(yīng)到 B 中的某個(gè)元素。

既然是映射,就可以通過字典的“鍵”找到相應(yīng)的“值”。

>>> person
{'name2': 'qiwsir', 'name': 'qiwsir', 'language': 'python', 'site': 'qiwsir.github.io'}
>>> person['name']
'qiwsir'
>>> person['language']
'python'

如同前面所講,通過“鍵”能夠增加 dict 中的“值”,通過“鍵”能夠改變 dict 中的“值”,通過“鍵”也能夠訪問 dict 中的“值”。

本節(jié)開頭那個(gè)城市和區(qū)號的關(guān)系,也可以用字典來存儲和讀取。

>>> city_code = {"suzhou":"0512", "tangshan":"0315", "beijing":"011", "shanghai":"012"}
>>> print city_code["suzhou"]
0512

既然 dict 是鍵值對的映射,就不用考慮所謂“排序”問題了,只要通過鍵就能找到值,至于這個(gè)鍵值對位置在哪里就不用考慮了。比如,剛才建立的 city_code

>>> city_code
{'suzhou': '0512', 'beijing': '011', 'shanghai': '012', 'tangshan': '0315'}

雖然這里顯示的和剛剛賦值的時(shí)候順序有別,但是不影響讀取其中的值。

在 list 中,得到值是用索引的方法。那么在字典中有索引嗎?當(dāng)然沒有,因?yàn)樗鼪]有順序,哪里來的索引呢?所以,在字典中就不要什么索引和切片了。

dict 中的這類以鍵值對的映射方式存儲數(shù)據(jù),是一種非常高效的方法,比如要讀取值得時(shí)候,如果用列表,Python 需要從頭開始讀,直到找到指定的那個(gè)索引值。但是,在 dict 中是通過“鍵”來得到值。要高效得多。 正是這個(gè)特點(diǎn),鍵值對這樣的形式可以用來存儲大規(guī)模的數(shù)據(jù),因?yàn)闄z索快捷。規(guī)模越大越明顯。所以,mongdb 這種非關(guān)系型數(shù)據(jù)庫在大數(shù)據(jù)方面比較流行了。

基本操作

字典雖然跟列表有很大的區(qū)別,但是依然有不少類似的地方。它的基本操作:

  • len(d),返回字典(d)中的鍵值對的數(shù)量
  • d[key],返回字典(d)中的鍵(key)的值
  • d[key]=value,將值(value)賦給字典(d)中的鍵(key)
  • del d[key],刪除字典(d)的鍵(key)項(xiàng)(將該鍵值對刪除)
  • key in d,檢查字典(d)中是否含有鍵為 key 的項(xiàng)

下面依次進(jìn)行演示。

>>> city_code
{'suzhou': '0512', 'beijing': '011', 'shanghai': '012', 'tangshan': '0315'}
>>> len(city_code)
4

以 city_code 為操作對象,len(city_code)的值是 4,表明有四組鍵值對,也可以說是四項(xiàng)。

>>> city_code["nanjing"] = "025"
>>> city_code
{'suzhou': '0512', 'beijing': '011', 'shanghai': '012', 'tangshan': '0315', 'nanjing': '025'}

向其中增加一項(xiàng)

>>> city_code["beijing"] = "010"
>>> city_code
{'suzhou': '0512', 'beijing': '010', 'shanghai': '012', 'tangshan': '0315', 'nanjing': '025'}

突然發(fā)現(xiàn)北京的區(qū)號寫錯(cuò)了??梢赃@樣修改。這進(jìn)一步說明字典是可變的。

>>> city_code["shanghai"]
'012'
>>> del city_code["shanghai"]

通過 city_code["shanghai"]能夠查看到該鍵(key)所對應(yīng)的值(value),結(jié)果發(fā)現(xiàn)也錯(cuò)了。干脆刪除,用 del,將那一項(xiàng)都刪掉。

>>> city_code["shanghai"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'shanghai'
>>> "shanghai" in city_code
False

因?yàn)殒I是"shanghai"的那個(gè)鍵值對項(xiàng)已經(jīng)刪除了,隨意不能找到,用 in 來看看,返回的是 False。

>>> city_code
{'suzhou': '0512', 'beijing': '010', 'tangshan': '0315', 'nanjing': '025'}

真的刪除了哦。沒有了。

字符串格式化輸出

這是一個(gè)前面已經(jīng)探討過的話題,請參看《字符串(4)》,這里再次提到,就是因?yàn)橛米值湟部梢詫?shí)現(xiàn)格式化字符串的目的。雖然在《字符串(4)》那節(jié)中已經(jīng)有了簡單演示,但是我還是愿意重復(fù)一下。

>>> city_code = {"suzhou":"0512", "tangshan":"0315", "hangzhou":"0571"}
>>> " Suzhou is a beautiful city, its area code is %(suzhou)s" % city_code
' Suzhou is a beautiful city, its area code is 0512'

這種寫法是非常簡潔,而且很有意思的。有人說它簡直是酷。

其實(shí),更酷還是下面的——模板

在做網(wǎng)頁開發(fā)的時(shí)候,通常要用到模板,也就是你只需要寫好 HTML 代碼,然后將某些部位空出來,等著 Python 后臺提供相應(yīng)的數(shù)據(jù)即可。當(dāng)然,下面所演示的是玩具代碼,基本沒有什么使用價(jià)值,因?yàn)樵谡鎸?shí)的網(wǎng)站開發(fā)中,這樣的姿勢很少用上。但是,它絕非花拳繡腿,而是你能夠明了其本質(zhì),至少了解到一種格式化方法的應(yīng)用。

>>> temp = "<html><head><title>%(lang)s<title><body><p>My name is %(name)s.</p></body></head></html>"
>>> my = {"name":"qiwsir", "lang":"python"}
>>> temp % my
'<html><head><title>python<title><body><p>My name is qiwsir.</p></body></head></html>'

temp 就是所謂的模板,在雙引號所包裹的實(shí)質(zhì)上是一段 HTML 代碼。然后在 dict 中寫好一些數(shù)據(jù),按照模板的要求在相應(yīng)位置顯示對應(yīng)的數(shù)據(jù)。

是不是一個(gè)很有意思的屠龍之技?

什么是 HTML? 下面是在《維基百科》上抄錄的:

超文本標(biāo)記語言(英文:HyperText Markup Language,HTML)是為「網(wǎng)頁創(chuàng)建和其它可在網(wǎng)頁瀏覽器中看到的信息」設(shè)計(jì)的一種標(biāo)記語言。HTML 被用來結(jié)構(gòu)化信息——例如標(biāo)題、段落和列表等等,也可用來在一定程度上描述文檔的外觀和語義。1982 年由蒂姆·伯納斯-李創(chuàng)建,由 IETF 用簡化的 SGML(標(biāo)準(zhǔn)通用標(biāo)記語言)語法進(jìn)行進(jìn)一步發(fā)展的 HTML,后來成為國際標(biāo)準(zhǔn),由萬維網(wǎng)聯(lián)盟(W3C)維護(hù)。

HTML 經(jīng)過發(fā)展,現(xiàn)在已經(jīng)到 HTML5 了?,F(xiàn)在的 HTML 設(shè)計(jì),更強(qiáng)調(diào)“響應(yīng)式”設(shè)計(jì),就是能夠兼顧 PC、手機(jī)和各種 PAD 的不同尺寸的顯示器瀏覽。如果要開發(fā)一個(gè)網(wǎng)站,一定要做到“響應(yīng)式”設(shè)計(jì),否則就只能在 PC 上看,在手機(jī)上看就不得不左右移動。

知識

什么是關(guān)聯(lián)數(shù)組?以下解釋來自維基百科

在計(jì)算機(jī)科學(xué)中,關(guān)聯(lián)數(shù)組(英語:Associative Array),又稱映射(Map)、字典(Dictionary)是一個(gè)抽象的數(shù)據(jù)結(jié)構(gòu),它包含著類似于(鍵,值)的有序?qū)?。一個(gè)關(guān)聯(lián)數(shù)組中的有序?qū)梢灾貜?fù)(如 C++ 中的 multimap)也可以不重復(fù)(如 C++ 中的 map)。

這種數(shù)據(jù)結(jié)構(gòu)包含以下幾種常見的操作:

  1. 向關(guān)聯(lián)數(shù)組添加配對
  2. 從關(guān)聯(lián)數(shù)組內(nèi)刪除配對
  3. 修改關(guān)聯(lián)數(shù)組內(nèi)的配對
  4. 根據(jù)已知的鍵尋找配對

字典問題是設(shè)計(jì)一種能夠具備關(guān)聯(lián)數(shù)組特性的數(shù)據(jù)結(jié)構(gòu)。解決字典問題的常用方法,是利用散列表,但有些情況下,也可以直接使用有地址的數(shù)組,或二叉樹,和其他結(jié)構(gòu)。

許多程序設(shè)計(jì)語言內(nèi)置基本的數(shù)據(jù)類型,提供對關(guān)聯(lián)數(shù)組的支持。而 Content-addressable memory 則是硬件層面上實(shí)現(xiàn)對關(guān)聯(lián)數(shù)組的支持。

什么是哈希表?關(guān)于哈希表的敘述比較多,這里僅僅截取了概念描述,更多的可以到維基百科上閱讀。

散列表(Hash table,也叫哈希表),是根據(jù)關(guān)鍵字(Key value)而直接訪問在內(nèi)存存儲位置的數(shù)據(jù)結(jié)構(gòu)。也就是說,它通過把鍵值通過一個(gè)函數(shù)的計(jì)算,映射到表中一個(gè)位置來訪問記錄,這加快了查找速度。這個(gè)映射函數(shù)稱做散列函數(shù),存放記錄的數(shù)組稱做散列表。


總目錄   |   上節(jié):元組   |   下節(jié):字典(2)

如果你認(rèn)為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。