學習了 python 基本的字典操作後,學習這些高階操作,讓寫出的**更加優雅簡潔和 pythonic 。
與字典值有關的計算
問題想對字典的值進行相關計算,例如找出字典裡對應值最大(最小)的項。
解決方案一:
假設要從字典 中找出值最小的項,可以這樣做:
>>> d =
>>> min(zip(d.values(), d.keys()))
(2, 'b')
值得注意的是 d.values() 獲取字典的全部值,d.keys() 獲取字典的全部鍵,而且兩個序列的順序依然保持一一對應的關係。因此 zip(d.values(), d.keys()) 實質上生成的是乙個 (value, key) 的序列。min 函式通過比較序列中的元組 (value, key) 找出其最小值。
解決方案二:
除了使用 zip(d.values(), d.keys()) 外,還可以使用 dict.items() 方法和生成器推導式來生成 (value, key) 序列,從而傳遞給 min 函式進行比較:
>>> d =
>>> min((v ,k) for (k, v) in d.items())
(2, 'b')
這裡 min 函式的引數 (v ,k) for (k, v) in d.items() 其實是乙個生成器推導式(和列表推導式一樣,只是把列表推導式的 改為 () ,而且其返回的乙個生成器而非列表),由於生成器推導式做為 min 函式的引數,所以可以省略掉兩邊的括號(不做為引數時寫法應該是 ((v ,k) for (k, v) in d.items()) )。
字典推導式
問題想把乙個元組列表轉換成乙個字典,例如把 [('a', 1), ('b', 2), ('c', 3)] 轉化為
解決方案
類似於列表推導式,字典推導式可以方便地從其他資料結構構造字典,例如:
>>> l = [('a', 1), ('b', 2), ('c', 3)]
>>>
字典推導式的規則和列表推導式一樣,只是把 換成 {}
尋找字典的交集
問題假設有兩個字典:
d1 =
d2 =
要找出這兩個字典中具有公共鍵的項,即要得到結果
解決方案
我們知道一般通過 d.items() 方法來遍歷字典,d.items() 方法返回的物件是乙個類集合物件,支援集合的基本運算,如取交集、並集等。
>>> dict(d1.items() & d2.items()) # 取交集
此外,d.keys() 返回字典的鍵,也是乙個類集合物件,如果我們只想找出兩個字典中鍵相同的項,可以這樣:
>>>
這裡如果相同的鍵對應不同的值則去第乙個字典中的值。推廣開來,如果想排除掉字典中的某些鍵,可以這樣:
>>> } # - 號的含義是集合的差集操作
但有一點需要注意的是,d.values() 返回字典的值,由於字典對應的值不一定唯一,所以 d.values() 一般無法構成乙個集合,因此也就不支援一般的集合操作。
多個字典連線成乙個字典
問題有多個字典,例如:
d1 =
d2 =
想將這多個字典連線為乙個字典,或一次性對多個字典進行迭代操作。
解決方案
使用 collections.chainmap :
>>> from collections import chainmap
>>> chain_dict = chainmap(d1, d2)
>>> for k, v in chain_dict.items():
print(k, v)
a 1e 6
d 5c 3
b 2chainmap 將傳入的多個字典連線為乙個字典,並返回乙個 chainmap 物件,這個物件的行為就像乙個單一的字典,我們可以對其進行取值或者迭代等操作。注意到這裡鍵 c 對應的值為 3,如果傳入 chainmap 的字典含有相同的鍵,則對應的值為先傳入的字典中的值。
此外,如果你只想單純地迭代字典的鍵值對,可以結合使用 items() 和 itertools.chain() 方法:
>>> from itertools import chain
>>> for k, v in chain(d1.items(), d2.items()):
print(k, v)
a 1c 3
b 2e 6
c 4d 5
這裡相同的鍵會被分別迭代出來。
保持字典有序
問題想讓字典中元素的迭代順序和其加入字典的順序保持一致
解決方案
通常來說,使用 d.items() 或者 d.keys()、d.values() 方法迭代出來的元素順序是無法預料的。例如對字典 d = 迭代:
>>> d = dict()
>>> d['a'] = 1
>>> d['b'] = 2
>>> d['c'] = 3
>>> for k, v in d.items():
print(k, v)
a 1c 3
b 2每一次執行結果都可能不同。如果想讓元素迭代的順序和建立字典時元素的順序一致,就要使用 collections.ordereddict 代替普通的 dict :
>>> from collections import ordereddict
>>> ordered_d = ordereddict()
>>> ordered_d['a'] = 1
>>> ordered_d['b'] = 2
>>> ordered_d['c'] = 3
>>> for k, v in ordered_d.items():
print(k, v)
a 1b 2
c 3ordereddict 實際通過維護乙個雙向鍊錶來記錄元素新增的順序,因此其耗費的記憶體大約為普通字典的兩倍。所以在實際使用中需綜合考慮各種因素來決定是否使用 ordereddict 。
使字典的鍵對映多個值
問題通常情況下字典的鍵只對應乙個值。現在想讓乙個鍵對應多個值。
解決方案
為了使乙個鍵對應多個值,首先需要把多個值放到乙個容器中(例如列表或者集合等)。例如有這樣乙個列表:[('a', 1), ('a', 2), ('b', 3), ('b', 4), ('c', 5)] ,我們要將其轉換成乙個字典,保持元素的鍵值對應關係,通常我們會寫這樣的**:
>>> from pprint import pprint
>>> l = [('a', 1), ('a', 2), ('b', 3), ('b', 4), ('c', 5)]
>>> d = {}
>>> for k, v in l:
if k in d:
else:
d[k] = [v]
>>> pprint(d)
但是 if else 語句讓**顯得有點冗餘和不易讀,python 的 defaultdict 改善上述**。
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for k, v in l:
>>> pprint(d)
defaultdict(, )
if else 的判語句沒有了。
傳入 defualtdict 構造器的值不一定要是乙個類,也可以是乙個可呼叫的函式,當相應的鍵不在 defualtdict 中時,其預設的值就為這個函式的返回值,例如:
>>> from collections import defaultdict
>>> def zero_default():
return 0
>>> d = defaultdict(zero_default)
>>> d['a'] = 1
>>> d['a']
>>> d['b']
>>> d.keys()
dict_keys(['b', 'a'])
利用這樣乙個特性,我們可以構造無限深度的字典結構:
>>> from collections import defaultdict
>>> import json
>>> tree = lambda: defaultdict(tree)
>>> d = tree()
>>> d['a']['b'] = 1
>>> print(json.dumps(d)) # 為了顯示的格式更好看
}這裡當執行 d['a'] 時,由於相應的鍵不存在,故返回乙個 defaultdict(tree),當再執行 d['a']['b'] = 1 時,將鍵 b 對應的值設為 1 。
python 字典操作
python 語法之字典 2009 10 21 磁針石 xurongzhong gmail.com 部落格 oychw.cublog.cn python essential reference 4th edition 2009 beginning python from novice to prof...
python 字典操作
1 什麼是字典?字典是python語言中唯一的對映型別。對映型別物件裡雜湊值 鍵,key 和指向的物件 值,value 是一對多的的關係,通常被認為是可變的雜湊表。字典物件是可變的,它是乙個容器型別,能儲存任意個數的python物件,其中也可包括其他容器型別。字典型別與序列型別的區別 1.訪問和訪問...
python字典操作
1 什麼是字典?字典是python語言中唯一的對映型別。對映型別物件裡雜湊值 鍵,key 和指向的物件 值,value 是一對多的的關係,通常被認為是可變的雜湊表。字典物件是可變的,它是乙個容器型別,能儲存任意個數的python物件,其中也可包括其他容器型別。字典型別與序列型別的區別 1.訪問和訪問...