從零學Python:第十五課-常用資料結構之字典

千鋒Python唐小強發表於2020-07-13

又是一次敲黑板的乾貨分享了!

迄今為止,我們已經為大家介紹了Python中的三種容器型資料型別,但是這些資料型別還不足以幫助我們解決所有的問題。例如,我們要儲存一個人的資訊,包括姓名、年齡、體重、單位地址、家庭住址、本人手機號、緊急聯絡人手機號等資訊,你會發現我們之前學過的列表、元組和集合都不是最理想的選擇。


person1 = [
'王大錘', 
55, 
60, 
'科華北路62號', 
'中同仁路8號', 
'13122334455', 
'13800998877']

person2 = ( '王大錘', 55, 60, '科華北路62號', '中同仁路8號', '13122334455', '13800998877')
person3 = { '王大錘', 55, 60, '科華北路62號', '中同仁路8號', '13122334455', '13800998877'}

集合肯定是最不合適的,因為集合有去重特性,如果一個人的年齡和體重相同,那麼集合中就會少一項資訊;同理,如果這個人的家庭住址和單位地址是相同的,那麼集合中又會少一項資訊。另一方面,雖然列表和元組可以把一個人的所有資訊都儲存下來,但是當你想要獲取這個人的手機號時,你得先知道他的手機號是列表或元組中的第6個還是第7個元素;當你想獲取一個人的家庭住址時,你還得知道家庭住址是列表或元組中的第幾項。總之,在遇到上述的場景時,列表、元組、字典都不是最合適的選擇,我們還需字典(dictionary)型別,這種資料型別最適合把相關聯的資訊組裝到一起,並且可以幫助我們解決程式中為真實事物建模的問題。

說到字典這個詞,大家一定不陌生,讀小學的時候每個人基本上都有一本《新華字典》,如下圖所示。

從零學Python:第十五課-常用資料結構之字典

Python程式中的字典跟現實生活中的字典很像,它以鍵值對(鍵和值的組合)的方式把資料組織到一起,我們可以透過鍵找到與之對應的值並進行操作。就像《新華字典》中,每個字(鍵)都有與它對應的解釋(值)一樣,每個字和它的解釋合在一起就是字典中的一個條目,而字典中通常包含了很多個這樣的條目。

建立和使用字典

在Python中建立字典可以使用{}字面量語法,這一點跟上一節課講的集合是一樣的。但是字典的{}中的元素是以鍵值對的形式存在的,每個元素由:分隔的兩個值構成,:前面是鍵,:後面是值,程式碼如下所示。

xinhua = {

    '麓': '山腳下', '路': '道,往來通行的地方;方面,地區:南~貨,外~貨;種類:他倆是一~人',
    '蕗': '甘草的別名', '潞': '潞水,水名,即今山西省的濁漳河;潞江,水名,即雲南省的怒江'
}
print(xinhua)
person = {
    'name': '王大錘', 'age': 55, 'weight': 60, 'office': '科華北路62號',
    'home': '中同仁路8號', 'tel': '13122334455', 'econtact': '13800998877'
}
print(person)

透過上面的程式碼,相信大家已經看出來了,用字典來儲存一個人的資訊遠遠優於使用列表或元組,因為我們可以用:前面的鍵來表示條目的含義,而:後面就是這個條目所對應的值。

當然,如果願意,我們也可以使用內建函式dict或者是字典的生成式語法來建立字典,程式碼如下所示。

# dict函式(構造器)中的每一組引數就是字典中的一組鍵值對

person = dict(name= '王大錘', age= 55, weight= 60, home= '中同仁路8號')
print(person)    # { 'name': '王大錘', 'age': 55, 'weight': 60, 'home': '中同仁路8號'}

# 可以透過Python內建函式zip壓縮兩個序列並建立字典
items1 = dict(zip( 'ABCDE', '12345'))
print(items1)    # { 'A': '1', 'B': '2', 'C': '3', 'D': '4', 'E': '5'}
items2 = dict(zip( 'ABCDE', range( 1, 10)))
print(items2)    # { 'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}

# 用字典生成式語法建立字典
items3 = {x: x ** 3 for x in range( 1, 6)}
print(items3)     # { 1: 1, 2: 8, 3: 27, 4: 64, 5: 125}

想知道字典中一共有多少組鍵值對,仍然是使用len函式;如果想對字典進行遍歷,可以用for迴圈,但是需要注意,for迴圈只是對字典的鍵進行了遍歷,不過沒關係,在講完字典的運算後,我們可以透過字典的鍵獲取到和這個鍵對應的值。

person = {
'name': 
'王大錘', 
'age': 
55, 
'weight': 
60, 
'office': 
'科華北路62號'}

print( len(person))    # 4
for key in person:
    print(key)

字典的運算

對於字典型別來說,成員運算和索引運算肯定是最為重要的,前者可以判定指定的鍵在不在字典中,後者可以透過鍵獲取對應的值或者向字典中加入新的鍵值對。值得注意的是,字典的索引不同於列表的索引,列表中的元素因為有屬於自己有序號,所以列表的索引是一個整數;字典中因為儲存的是鍵值對,所以字典的索引是鍵值對中的鍵,透過索引操作可以修改原來的值或者向字典中存入新的鍵值對。需要 特別提醒大家注意的是, 字典中的鍵必須是不可變型別,例如整數(int)、浮點數(float)、字串(str)、元組(tuple)等型別的值;顯然,列表(list)和集合(set)是不能作為字典中的鍵的,當然字典型別本身也不能再作為字典中的鍵,因為字典也是可變型別,但是字典可以作為字典中的值。關於可變型別不能作為字典中的鍵的原因,我們在後面的課程中再為大家詳細說明。這裡,我們先看看下面的程式碼,瞭解一下字典的成員運算和索引運算。

person = {
'name': 
'王大錘', 
'age': 
55, 
'weight': 
60, 
'office': 
'科華北路62號'}

# 檢查name和tel兩個鍵在不在person字典中
print( 'name' in person, 'tel' in person)    # True False
# 透過age修將person字典中對應的值修改為 25
if 'age' in person:
   person[ 'age'] = 25
# 透過索引操作向person字典中存入新的鍵值對
person[ 'tel'] = '13122334455'
person[ 'signature'] = '你的男朋友是一個蓋世垃圾,他會踏著五彩祥雲去贏取你的閨蜜'
print( 'name' in person, 'tel' in person)    # True True
# 檢查person字典中鍵值對的數量
print( len(person))    # 6
# 對字典的鍵進行迴圈並通索引運算獲取鍵對應的值
for key in person:
    print(f '{key}: {person[key]}')

需要注意,在透過索引運算獲取字典中的值時,如指定的鍵沒有在字典中,將會引發KeyError異常。

字典的方法

字典型別的方法基本上都跟字典的鍵值對操作相關,可以透過下面的例子來了解這些方法的使用。例如,我們要用一個字典來儲存學生的資訊,我們可以使用學生的學號作為字典中的鍵,透過學號做索引運算就可以得到對應的學生;我們可以把字典中鍵對應的值也做成一個字典,這樣就可以用多組鍵值對分別儲存學生的姓名、性別、年齡、籍貫等資訊,程式碼如下所示。

# 字典中的值又是一個字典(巢狀的字典)

students = {
    1001: { 'name': '狄仁傑', 'sex': True, 'age': 22, 'place': '山西大同'},
    1002: { 'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'},
    1003: { 'name': '武則天', 'sex': False, 'age': 20, 'place': '四川廣元'}
}

# 使用get方法透過鍵獲取對應的值,如果取不到不會引發KeyError異常而是返回None或設定的預設值
print(students.get( 1002))    # { 'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}
print(students.get( 1005))    # None
print(students.get( 1005, { 'name': '無名氏'}))    # { 'name': '無名氏'}

# 獲取字典中所有的鍵
print(students.keys())      # dict_keys([ 1001, 1002, 1003])
# 獲取字典中所有的值
print(students.values())    # dict_values([{...}, {...}, {...}])
# 獲取字典中所有的鍵值對
print(students.items())     # dict_items([( 1001, {...}), ( 1002, {....}), ( 1003, {...})])
# 對字典中所有的鍵值對進行迴圈遍歷
for key, value in students.items():
    print(key, '--->', value)

# 使用pop方法透過鍵刪除對應的鍵值對並返回該值
stu1 = students.pop( 1002)
print(stu1)             # { 'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}
print( len(students))    # 2
# stu2 = students.pop( 1005)    # KeyError: 1005
stu2 = students.pop( 1005, {})
print(stu2)             # {}

# 使用popitem方法刪除字典中最後一組鍵值對並返回對應的二元組
# 如果字典中沒有元素,呼叫該方法將引發KeyError異常
key, value = students.popitem()
print(key, value)    # 1003 { 'name': '武則天', 'sex': False, 'age': 20, 'place': '四川廣元'}

# setdefault可以更新字典中的鍵對應的值或向字典中存入新的鍵值對
# setdefault方法的第一個引數是鍵,第二個引數是鍵對應的值
# 如果這個鍵在字典中存在,更新這個鍵之後會返回原來與這個鍵對應的值
# 如果這個鍵在字典中不存在,方法將返回第二個引數的值,預設為None
result = students.setdefault( 1005, { 'name': '方啟鶴', 'sex': True})
print(result)        # { 'name': '方啟鶴', 'sex': True}
print(students)      # { 1001: {...}, 1005: {...}}

# 使用update更新字典元素,相同的鍵會用新值覆蓋掉舊值,不同的鍵會新增到字典中
others = {
    1005: { 'name': '喬峰', 'sex': True, 'age': 32, 'place': '北京大興'},
    1010: { 'name': '王語嫣', 'sex': False, 'age': 19},
    1008: { 'name': '鍾靈', 'sex': False}
}
students.update(others)
print(students)      # { 1001: {...}, 1005: {...}, 1010: {...}, 1008: {...}}

跟列表一樣,從字典中刪除元素也可以使用del關鍵字,在刪除元素的時候如果指定的鍵索引不到對應的值,一樣會引發KeyError異常,具體的做法如下所示。

person = {
'name': 
'王大錘', 
'age': 
25, 
'sex': True}

del person[ 'age']
print(person)    # { 'name': '王大錘', 'sex': True}

字典的應用

我們透過幾個簡單的例子來講解字典的應用。

例子1:輸入一段話,統計每個英文字母出現的次數。

sentence = input(
'請輸入一段話: ')

counter = {}
for ch in sentence:
    if 'A' <= ch <= 'Z' or 'a' <= ch <= 'z':
       counter[ch] = counter.get(ch, 0) + 1
for key, value in counter.items():
   print( f'字母 {key}出現了 {value}次.')

例子2:在一個字典中儲存了股票的程式碼和價格,找出股價大於100元的股票並建立一個新的字典。

說明:可以用字典的生成式語法來建立這個新字典。


stocks 
= 
{

    'AAPL': 191.88 ,
    'GOOG': 1186.96 ,
    'IBM': 149.24 ,
    'ORCL': 48.44 ,
    'ACN': 166.89 ,
    'FB': 208.09 ,
    'SYMC': 21.29
}
stocks2 = {key: value for key, value in stocks.items() if value > 100 }
print(stocks2)

簡單的總結

Python程式中的字典跟現實生活中字典非常像,允許我們 以鍵值對的形式儲存資料,再 透過鍵索引對應的值。這是一種非常 有利於資料檢索的資料型別,底層原理我們在後續的課程中再研究。再次提醒大家注意, 字典中的鍵必須是不可變型別,字典中的值可以是任意型別。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69923331/viewspace-2704178/,如需轉載,請註明出處,否則將追究法律責任。

相關文章