Python學習筆記 - 8.字典(Dict)

與列表相比的特點:

列表中的索引位置必須是整數,而字典中索引幾乎可以是任意類型

字典

字典可看作是索引(這裏稱爲鍵)的集合值的集合之間存在的一種映射
每個鍵對應一個值,鍵與值之間的關係稱之爲鍵值對,有時也稱爲數據項
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的元組。

調試

編寫自檢程序:

有時通過編寫代碼來自動檢查錯誤。例如,需要計算數字列表的平均數,你可以檢查這個結果是不是處於列
表的最大值與最小值之間。這種檢查稱爲“邏輯檢查”,它會檢測出哪些結果是完全不符合邏輯的。

一致性檢查

比較兩種不同計算的結果,檢查它們是否一致。。

工整化輸出結果:

對調試的輸出結果進行格式化,這有助於發現錯誤。

再次強調,在程序架構上花些心思能有效減少調試的時間花費。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章