與列表相比的特點:
列表中的索引位置必須是整數,而字典中索引幾乎可以是任意類型。
字典
字典可看作是索引(這裏稱爲鍵)的集合與值的集合之間存在的一種映射。
每個鍵對應一個值,鍵與值之間的關係稱之爲鍵值對,有時也稱爲數據項。
dict函數(內置函數)可以創建一個空字典。
>>> eng2sp = dict()
>>> print eng2sp
{}
大括號{}表示一個空字典。你可以使用方括號向字典裏添加數據項。
>>> eng2sp['one'] = 'uno'
這行語句創建了一個從鍵“one”到值“uno”映射的字典項。如果再次打印這個字典,我們會看到一個鍵值對,鍵與值之間用冒
號隔開。
>>> print eng2sp
{'one': 'uno'}
字典的輸入形式與輸出形式是一樣的。舉例來說,你可以創建一個包含三個數據項的字典:
>>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
但是,如果你直接打印eng2sp,其結果會出人意料:
>>> print eng2sp
{'one': 'uno', 'three': 'tres', 'two': 'dos'}
輸出的鍵值對順序發生了改變。一般而言,字典的順序往往不可預測。
這個無所謂。因爲字典項不是用整數來索引,而是採用鍵來查找對應的值。
>>> print eng2sp['two']
'dos'
鍵“two”對應的值是“dos”,這與字典項的順序無關。
len函數也適用於字典,它會返回字典中鍵值對的個數。
>>> len(eng2sp)
3
in操作符也適用於字典,它會告知你查找的東西是否作爲鍵存在於字典中,但不能對是否是值作出很好的判斷。
>>> 'one' in eng2sp
True
>>> 'uno' in eng2sp
False
爲了判斷要找的東西是否作爲值存在於字典中,使用values方法,它會返回字典中所有值的一個列表,然後使用in操作符作
出判斷。
>>> vals = eng2sp.values()
>>> 'uno' in vals
True
字典作爲計數器
字典實現的一個優點在於,我們不必事先知道字符串中出現了哪些字母,只需爲確實會出現的字母分配空間就好了。
word = 'brontosaurus'
d = dict()
for c in word:
if c not in d:
d[c] = 1
else:
d[c] = d[c] + 1
print d
每次循環時,如果字符c不在字典中,我們就創建一個字典項,以c爲鍵,初始值1(表示這個字母至此出現了一次)。如果c已經存在於字典中,只需將對應值d[c]加1即可。
字典有一個get方法,該方法擁有一個鍵和一個默認值。**如果鍵出現在字典中,那麼它會返回此鍵對應的值。如果鍵不在字典
中,返回事先給定的默認值**。示例程序如下:
>>> counts = {'chuck':1 ,'annie':42,'jan':100}
>>> print counts.get('jan', 0)
100
>>> print counts.get('tim', 0)
0
我們使用get方法可以把直方圖循環寫得更簡潔。因爲get方法自動處理了鍵不在字典中的情況。這樣的話,代碼的4條語句可
縮減至1條,還可以去掉if語句。
word = 'brontosaurus'
d = dict()
for c in word:
d[c] = d.get(c,0) + 1
print d
使用get方法簡化計數循環的做法已經成爲Python中的一種普遍做法。
字典與文件
字典的常見用法之一是對書面文字的文本文件進行詞頻統計。
編寫一個Python程序,讀取文件的每一行,並將每一行*分解爲由單詞組成的一個列表*。然後,遍歷每個單詞,使用字典來統計每個單詞的出現次數。
fname = raw_input('Enter the file name: ')
try:
fhand = open(fname)
except:
print 'File cannot be opened:', fname
exit()
counts = dict()
for line in fhand:
words = line.split() #通過指定字符對字符串進行切片
for word in words:
if word not in counts:##這句話注意怎麼寫***
counts[word] = 1
else:
counts[word] += 1
print counts
split()方法 :通過指定字符對字符串進行切片
循環與字典
通過for語句循環讀取每一個鍵及其對應的值:
counts = { 'chuck':1, 'annie':42,'jan':100}
for key in counts:
print key,counts[key]
程序運行結果如下:
jan 100
chuck 1
annie 42
如果按照字母順序輸出字典中的鍵,首先使用字典對象的keys方法,將所有的鍵放入一個列表。然後,對這個列表進行排
序,對排序後的列表進行迭代。依照字母順序,通過每個鍵輸出對應的鍵值對:
counts = {'chuck':1,'annie':42,'jan':100}
lst = counts.keys()
print lst
lst.sort()
for key in lst:
print key,counts[key]
程序運行的輸出結果如下:
['jan', 'chuck', 'annie']
annie 42
chuck 1
jan 100
首先,通過keys方法得到了包含鍵的未排序的列表。然後,通過for循環得到有序的鍵值對。
高級文本解析
實際的文本會包含大量標點符號:
通過字符串的lower(大小寫轉換)、punctuation(列出標點符號需要哪些字符)與translate(刪除指定的所有字符)方法可以解決上述問題。其中translate是最精細的方法。
Translate方法使用:
string.translate(s, table[, deletechars])
首先,從s中刪除deletechars參數(如果存在的話)指定的所有字符,然後使用table參數來翻譯字符。table是一個256個字
符長的字符串,用來翻譯每個字符值,並按照序數進行索引。如果table是None值,只會執行字符刪除步驟。
這裏不指定table參數,用deletechars參數來刪除所有標點符號。
Python甚至可以告訴我們,標點符號包括哪些字符:
>>> import string
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
我們對程序做出如下修改:
import string
#New Code
fname = raw_input('Enter the file name:')
try:
fhand = open(fname)
except:
print 'File cannot be opened:',fname
exit()
counts = dict()
for line in fhand:
line = line.translate(None, string.punctuation)
#New Code 這行代碼好好看看
line = line.lower()
#New Code
words = line.split()
for word in words:
if word not in counts:
counts[word] = 1
else:
counts[word] += 1
print counts
我們使用translate方法刪除了所有的標點符號,並將每一行中的字母轉換爲小寫。
查看這些輸出仍然很費事,讓Python來幫助我們找到具體要找到的信息。要做到這一點,我們需要學習Python的元組。
調試
編寫自檢程序:
有時通過編寫代碼來自動檢查錯誤。例如,需要計算數字列表的平均數,你可以檢查這個結果是不是處於列
表的最大值與最小值之間。這種檢查稱爲“邏輯檢查”,它會檢測出哪些結果是完全不符合邏輯的。
一致性檢查
比較兩種不同計算的結果,檢查它們是否一致。。
工整化輸出結果:
對調試的輸出結果進行格式化,這有助於發現錯誤。
再次強調,在程序架構上花些心思能有效減少調試的時間花費。