字典 ( dictionary )跟串列類似,都能作為儲存資料的容器,可以放入字串、整數、布林、串列或字典,顧名思義就像「查詢用的字典」一樣,透過要查詢的「鍵 key」( 關鍵字 ),就能夠查詢到對應的「值 value」( 解釋說明 ),也是使用頻率相當高的資料型態。
原文參考:字典 dictionary
本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )
建立字典有兩種方法,建立時必須要包含「鍵 key」和「值 value」兩個項目,鍵在左側,值在右側。
字典和串列的差別在於串列有「順序性」,串列中的項目都有各自的索引值 offset,但字典中的項目沒有順序性,是按照鍵 key 的位置來做紀錄。
大括號 {}
使用大括號建立字典是最常見的建立字典方式,使用方式為「{'鍵':值}
」,鍵必須是「字串」,前後必須加上「引號」,值則可以是任意的 Python 物件 ( 字串、數字、串列、字典...等 ),不同鍵值中間使用逗號「,」分隔。
下方的程式碼,第一個鍵為 name 值為字串 oxxo,第二個鍵為 age 值為數字 18,第三個鍵為 eat 值為串列,最後印出 a 的 type 型別是 dict 字典。
a = {'name':'oxxo','age':18,'eat':['apple','banana']}
print(type(a)); # <class 'dict'>
單純只要使用大括號,可以建立一個空的字典。
a = {}
print(type(a)); # <class 'dict'>
dict()
使用 dict() 建立字典使用「dict(鍵=值)
」,注意鍵的前後「不需要加上引號」。
a = dict(name='oxxo', age=18, eat=['apple','banana'])
print(a) # {'name': 'oxxo', 'age': 18, 'eat': ['apple', 'banana']}
print(type(a)); # <class 'dict'>
dict() 函式除了可以建立字典,也可以將有「兩個值的二維串列或 tuple」轉換成字典,轉換時會將第一個值當作鍵,第二個當成值。
a = [['x','100'],['y','200'],['z','300']]
b = dict(a)
print(b) # {'x': '100', 'y': '200', 'z': '300'}
如果是「雙字元」的字串串列或 tuple,也可以使用 dict() 轉換成字典。
a = ['ab','cd','ef']
b = dict(a)
print(b) # {'a': 'b', 'c': 'd', 'e': 'f'}
讀取字典的項目時,有別於串列或 tuple 使用索引值 offset,只要知道字典的鍵,就能讀取對應的值。
中括號 []
使用「字典['鍵']
」的方式,就能讀取對應的值,如果讀取到的是串列或 tuple,就可以使用讀取串列或 tuple 的方式取出對應的項目,例如下方程式的變數 c,先取出串列,接著再取出串列的第一個項目。
a = {'name':'oxxo', 'age':18, 'eat':['apple','banana']}
b = a['name']
c = a['eat'][0]
print(b) # oxxo
print(c) # apple
get()
使用中括號取值時,如果沒有對應的鍵,就會發生錯誤,如果要避免這種情況,就可以使用 get() 函式來取值,使用方法為「get('鍵')
」,如果有鍵就會回傳值,如果找不到鍵,就會回傳 None。
a = {'name':'oxxo', 'age':18, 'eat':['apple','banana']}
b = a.get('name')
c = a.get('school')
print(b) # oxxo
print(c) # None
字典內的所有元素都是可以修改的,修改的方法有兩種:
中括號 []
透過「字典['鍵']=新值
」的方式,就能夠將字典中某個鍵對應的值,修改為新的值,下方程式碼將 name 換成 XXXX,age 換成 100。
a = {'name':'oxxo', 'age':18}
a['name'] = 'XXXX'
a['age'] = 100
print(a) # {'name': 'XXXX', 'age': 100}
如果修改字典時,鍵不存在於字典中,會直接加入一個新的鍵和值,例如下方程式碼,原本的字典中沒有 ok 這個鍵,所以執行後就會將鍵為 ok 值為 True 的項目加入字典中。
a = {'name':'oxxo', 'age':18}
a['name'] = 'XXXX'
a['age'] = 100
a['ok'] = True
print(a) # {'name': 'XXXX', 'age': 100, 'ok': True}
setdefault()
setdefault() 函式用法和 get() 類似,都是可以取出某個鍵的值,但如果字典中沒有對應的鍵,執行 setdefault() 就會將新的鍵和值加入字典中,使用的方式為「setdefault('鍵',值)
」,第二個值只針對「新的鍵」才有作用,下方的程式碼,變數 b 取得的值仍然是 18 ( 因為 a 原本的 age 就是 18 ),但 c 取到 True 之後,字典 a 裡就會加入 ok 為 True 的項目。
a = {'name':'oxxo', 'age':18}
b = a.setdefault('age', 100)
c = a.setdefault('ok', True)
print(a) # {'name': 'oxxo', 'age': 18, 'ok': True}
print(b) # 18
print(c) # True
刪除字典有三種做法,包含了刪除個別的鍵值,清空個字典或將整個字典移除:
del
使用「del 字典['鍵']
」可以刪除字典中個別的鍵值,如果使用「del 字典
」,則會將整個字典刪除 ( 從記憶體中消失 ),下方程式碼可以看出,刪除了鍵為 name 的字典 a,只剩下 age 一個鍵,不過如果刪除了整個字典 b,讀取 b 時就會發生錯誤。
a = {'name':'oxxo', 'age':18}
del a['name']
print(a) # {'age': 18}
b = {'name':'oxxo', 'age':18}
del b
print(b) # name 'b' is not defined
pop()
使用「pop('鍵')
」可以將字典中某個鍵「取得並移出」,如果沒有賦值給任何變數,這個鍵值就會刪除,下方程式碼會將 name 從字典 a 中取出並移除,並將 name 賦值給 b ( 注意,有別於串列的 pop() 可為空,字典的 pop('鍵') 操作一定要有鍵,不然會發生錯誤 )。
a = {'name':'oxxo', 'age':18}
b = a.pop('name')
print(a) # {'age': 18}
print(b) # oxxo
clear()
使用「字典.clear()
」可以將字典中所有項目刪除,變成一個空的字典。
a = {'name':'oxxo', 'age':18}
a.clear()
print(a) # {}
如果要將多個字典結合成一個字典,Python 提供兩種方法:
兩個星號**
使用兩個星號「**字典
」,會將字典拆解為 keyword arguments 列表,再透過大括號組合,就可以將不同的字典結合為新的字典,下面的程式碼,a、b、c 就會結合成 d。
a = {'name':'oxxo', 'age':18}
b = {'weight':60, 'height':170}
c = {'ok':True}
d = {**a, **b, **c}
print(d) # {'name': 'oxxo', 'age': 18, 'weight': 60, 'height': 170, 'ok': True}
update()
使用「字典1.update(字典2)
」,會將字典 2 的內容與字典 1 結合,下面的程式碼,會將 b 和 c 依序和 a 結合。
a = {'name':'oxxo', 'age':18}
b = {'weight':60, 'height':170}
c = {'ok':True}
a.update(b)
a.update(c)
print(a) # {'name': 'oxxo', 'age': 18, 'weight': 60, 'height': 170, 'ok': True}
字典由鍵和值組成,透過「字典.keys()
」能夠將所有的鍵取出變成「dict_keys()」,透過「字典.values()
」能夠將所有的值取出變成「dict_values()」,兩者都可以透過串列或 tuple 的方法,轉換成串列或 tuple。
a = {'name':'oxxo', 'age':18, 'weight':60, 'height':170}
b = a.keys()
c = a.values()
print(b) # dict_keys(['name', 'age', 'weight', 'height'])
print(c) # dict_values(['oxxo', 18, 60, 170])
print(list(b)) # ['name', 'age', 'weight', 'height']
print(list(c)) # ['oxxo', 18, 60, 170]
in 可以判斷某個鍵是否存在於字典中,使用方法為「鍵 in 字典
」,如果字典中存在這個鍵,就會回傳 True,如果不存在,就回傳 Fasle。
a = {'apple':10, 'banana':20, 'orange':30}
print('apple' in a) # True
print('grap' in a) # False
Python 提供兩種複製字典的方法:
copy()
copy() 可以快速複製一個新的字典,使用方式為「字典.copy()
」。
a = {'x':10, 'y':20, 'z':30}
b = a.copy()
print(b) # {'x': 10, 'y': 20, 'z': 30}
deepcopy()
copy() 的方法只能針對「項目內容不會發生變化」的字典,如果字典的「深層內容」會發生變化,就會出現奇怪的現象,舉例來說,下方的程式碼執行後,當 a 改變時理應不該影響到 b,但執行結果卻發現 b 的內容也跟著改變了。
a = {'x':10, 'y':20, 'z':[100,200,300]}
b = a.copy()
a['z'][0] = 999
print(a) # {'x': 10, 'y': 20, 'z': [999, 200, 300]}
print(b) # {'x': 10, 'y': 20, 'z': [999, 200, 300]}
如果要解決這個問題,就必須要 import copy() 模組,使用 deepcopy() 進行深度複製,就能產生一個完全獨立的新串列。
import copy
a = {'x':10, 'y':20, 'z':[100,200,300]}
b = copy.deepcopy(a)
a['z'][0] = 999
print(a) # {'x': 10, 'y': 20, 'z': [999, 200, 300]}
print(b) # {'x': 10, 'y': 20, 'z': [100, 200, 300]} 使用 deepcopy 的沒有被改變