問題
怎樣在資料字典中執行一些計算操作(從而實現求最小值、最大值或排序等等)?
如何能根據某個或某幾個字典欄位來排序一個字典列表?
如何建立一個字典,並且在迭代或序列化這個字典的時候能夠控制元素的順序?
解決方案
zip( )函式
operator模組的itemgetter函式
OrderedDict 有序字典
zip( )
1. 為了對字典值執行計算操作,通常需要使用zip( )函式先將鍵和值反轉過來
2. 從而我們能將zip和sorted( )、max( )、min( )函式結合使用,來實現排列字典資料
prices = { 'ACME': 37.20, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.20, 'FB': 10.75 } print(min(prices),max(prices)) #直接對字典執行普通的數學運算,其只會對key操作 AAPL IBM print(min(prices.values()),max(prices.values())) #可通過字典的values函式解決,但輸出時只能看到values 10.75 612.78 print(min(prices,key=lambda x:prices[x])) #可通過min/max的key屬性函式解決,但輸出同樣不好看 FB print(min(zip(prices.values(),prices.keys()))) #先通過zip()將字典”反轉”為(value,key)的元組序列 (10.75, 'FB') print(sorted(zip(prices.values(),prices.keys()))) #若恰巧出現values相同的情況,則根據key的排序結果返回 [(10.75, 'FB'), (37.2, 'ACME'), (37.2, 'HPQ'), (205.55, 'IBM'), (612.78, 'AAPL')]
3. 執行這些計算的時候,需要注意的是zip( )函式建立的是一個只能訪問一次的迭代器
prices_and_names=zip(prices.values(),prices.keys()) print(max(prices_and_names)) (612.78, 'AAPL') print(max(prices_and_names)) #第二次再用就報錯了 ValueError: max() arg is an empty sequence
operator模組的itemgetter函式
1. sorted(rows,key=itemgetter)
from operator import itemgetter rows = [ {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004} ] #根據任意的字典欄位key來排序 rows_by_uid=sorted(rows,key=itemgetter('uid')) print(rows_by_uid) [{'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}, {'uid': 1002, 'lname': 'Beazley', 'fname': 'David'}, {'uid': 1003, 'lname': 'Jones', 'fname': 'Brian'}, {'uid': 1004, 'lname': 'Jones', 'fname': 'Big'}] #也支援多個 keys rows_by_lfname = sorted(rows, key=itemgetter('lname','fname')) print(rows_by_lfname) [{'uid': 1002, 'lname': 'Beazley', 'fname': 'David'}, {'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}, {'uid': 1004, 'lname': 'Jones', 'fname': 'Big'}, {'uid': 1003, 'lname': 'Jones', 'fname': 'Brian'}] #應當注意,以上兩個排序語句等價於: rows_by_fname = sorted(rows, key=lambda r: r['uid']) rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname'])) #但使用 itemgetter() 方式會執行的稍微快點
2. itemgetter同樣適用於min( )和max( )等函式
rows_min_uid=min(rows, key=itemgetter('uid')) print(rows_min_uid) {'uid': 1001, 'lname': 'Cleese', 'fname': 'John'}
OrderedDict 有序字典
1. 為了能控制一個字典中元素的順序,你可以使用 collections
模組中的 OrderedDict
類。 在迭代操作的時候它會保持元素被插入時的順序
from collections import OrderedDict d={} d[0]=3;d[6]=1;d[3]=1 //仔細看插入順序 for k,v in d.items(): print(k,v) //輸出的時候dict字典會按照key順序來排序 0 3 3 1 6 1 od=OrderedDict() od[0]=3;od[6]=1;od[3]=1 //但同樣的插入順序下 for k,v in od.items(): print(k,v) //OrdereDict會保持插入順序 0 3 6 1 3 1
2. 需要注意的是,一個 OrderedDict 的大小是一個普通字典的兩倍,因為它內部維護著另外一個連結串列,要注意記憶體消耗問題