Python 進階編程之字典的高級用法

1、 collections 中 defaultdict 的使用

1.1 字典的鍵映射多個值

將下面的列表轉成字典python

l = [('a',2),('b',3),('a',1),('b',4),('a',3),('a',1),('b',3)]
複製代碼

一個字典就是一個鍵對應一個單值的映射,而上面的列表中有相同鍵。若是你想要一個鍵映射多個值,那麼就須要將這多個值放到另外的序列中,好比 list 或者 set 裏面,像下面這樣:編程

d = {
    'a': [1, 2, 3],
    'b': [4, 5]
}
e = {
    'a': {1, 2, 3},
    'b': {4, 5}
}
複製代碼

你能夠很方便的使用 collections 模塊中的 defaultdict 來構造這樣的字典。 defaultdict 的一個特徵是它會自動初始化每一個 key 剛開始對應的值。微信

In [1]: l = [('a',2),('b',3),('a',1),('b',4),('a',3),('a',1),('b',3)]

In [2]: from collections import defaultdict

In [3]: d = defaultdict(list)

In [4]: for key, value in l:
   ...:     d[key].append(value)
   ...: 

In [5]: d
Out[5]: defaultdict(list, {'a': [2, 1, 3, 1], 'b': [3, 4, 3]})

複製代碼

固然這個默認的容器不必定是 list, 也能夠是集合 set。根據本身的需求選擇用 list 仍是 set 。若是你想保持元素的插入順序就應該使用列表,若是想去掉重複元素就使用集合!數據結構

1.2 統計字典中某個值出現的次數

來源於微信交流羣裏一個朋友工做中的問題,列表中有不少字典,須要統計字典中相同的鍵對應的值的和app

利用 defaultdict 設置默認值的方法 defaultdict(int),代碼以下:函數

In [6]: d = defaultdict(int)

In [7]: objs = [{'F29958SVDK6': 12}, {'F29958SVDK6': 12}, {'F29958SVDK6': 12}, {'F29958SVDK6': 12}, {'F29958SVDK6': 12}]

In [8]: for obj in objs:
   ...:     for key,value in obj.items():
   ...:         d[key] += value
   ...: 

In [9]: d
Out[9]: defaultdict(int, {'F29958SVDK6': 60})
複製代碼

2、collections 建立有序字典

字典dict是無序的,若是咱們想要有序的dict,可使用OrdereDict 。示例以下:ui

In [11]: from collections import OrderedDict

In [12]: d = OrderedDict()

In [13]: d['bar'] = 2

In [14]: d['non'] = 8

In [15]: d['sek'] = 5

In [16]: d
Out[17]: OrderedDict([('bar', 2), ('non', 8), ('sek', 5)])
複製代碼

OrderedDict 內部維護着一個根據鍵插入順序排序的雙向鏈表。每次當一個新的元 素插入進來的時候,它會被放到鏈表的尾部。對於一個已經存在的鍵的重複賦值不會 改變鍵的順序。spa

須要注意的是,一個 OrderedDict 的大小是一個普通字典的兩倍,由於它內部維 護着另一個鏈表。因此若是你要構建一個須要大量 OrderedDict 實例的數據結構的 時候 (好比讀取 100,000 行 CSV 數據到一個 OrderedDict 列表中去),那麼你就得仔細權衡一下是否使用 OrderedDict 帶來的好處要大過額外內存消耗的影響。code

2.1 改變 key-value 的順序

OrderedDict 是有序的字典,同時也能改變其順序。好比咱們想要改變有序的 OrderedDict 對象的 key-value 順序,可使用 move_to_end(key)。仍是以上面建立的有序字典爲例子cdn

In [18]: d.move_to_end("bar")

In [20]: d
Out[20]: OrderedDict([('non', 8), ('sek', 5), ('bar', 2)])
複製代碼

能夠看到以前排在第一位的 bar被移到最後一位了。move_to_end 還接收一個關鍵字參數 last。last 默認爲 True,當 last = False 的時候,表示將該鍵移動到最前面!

2.2 刪除 key_value

若是咱們要刪除有序字典中的 key-value, 可使用 popitem 方法, popitem(last=True) 按照先進後出的順序刪除 dict中 的 key-value,popitem(last=False) 按照先進先出的規則刪除 dict 中的 key-value。

In [42]: d
Out[42]: OrderedDict([('bar', 2), ('non', 8), ('sek', 5)])

In [43]: d.popitem(last=False)
Out[43]: ('bar', 2)

In [44]: d
Out[44]: OrderedDict([('non', 8), ('sek', 5)])
複製代碼

3、字典排序

利用Python 內置函數 sorted 對字典的鍵或者值進行排序,首先來了解下 sorted 函數

sorted(iterable, key=None, reverse=False)

參數說明:

  • iterable -- 可迭代對象

  • key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中,指定可迭代對象中的一個元素來進行排序。

  • reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(默認)。

3.1 按照 key 進行排序

理解了 sorted 函數就好辦了,代碼以下:

In [55]: d = {'b':3,'a':4,'c':2,'d':1}

In [57]: d.items()
Out[57]: dict_items([('b', 3), ('a', 4), ('c', 2), ('d', 1)])

In [58]: sorted(d.items(), key=lambda i:i[0])
Out[58]: [('a', 4), ('b', 3), ('c', 2), ('d', 1)]
複製代碼

3.2 按照 value 進行排序

代碼以下:

In [59]: sorted(d.items(), key=lambda i:i[1])
Out[59]: [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
複製代碼

注意排序後的返回值是一個list,而原字典中的名值對被轉換爲了list中的元組。

4、經過某個關鍵字排序一個字典列表

假設你有一個字典列表, 以下:

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} ] 
複製代碼

你想根據某個或某幾個字典字段來排序這個列表。

經過使用 operator 模塊的 itemgetter 函數,能夠很是容易的排序這樣的數據結構,代碼以下:

In [46]: from operator import itemgetter

In [47]: rows_by_fname = sorted(rows, key=itemgetter('fname'))

In [48]: rows_by_fname
Out[48]: 
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]

In [49]: rows_by_uid = sorted(rows, key=itemgetter('uid'))

In [50]: rows_by_uid
Out[50]: 
[{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
複製代碼

itemgetter() 函數也支持多個 keys,好比下面的代碼:

In [52]: rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))

In [53]: rows_by_fname
Out[53]: 
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
複製代碼

歡迎關注公衆號【Python編程與實戰】 獲取更多資料!

相關文章
相關標籤/搜索