每日一課 | Python 進階編程之字典的高級用法

一、 collections 中 defaultdict 的使用

1.1 字典的鍵映射多個值

將下面的列表轉成字典

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 剛開始對應的值。

from collections import defaultdict

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

#集合方式
d = defaultdict(set)
for key, value in l:
    d[key].add(value)

#列表方式
d = defaultdict(list)
for key, value in l:
    d[key].append(value)
print(d)

print(defaultdict(list, {'a': [2, 1, 3, 1], 'b': [3, 4, 3]}))

當然這個默認的容器不一定是 list, 也可以是集合 set降盹。根據(jù)自己的需求選擇用 list 還是 set 。如果你想保持元素的插入順序就應該使用列表谤辜,如果想去掉重復元素就使用集合蓄坏!

1.2 統(tǒng)計字典中某個值出現(xiàn)的次數(shù)

來源于微信交流群里一個朋友工作中的問題,列表中有很多字典丑念,需要統(tǒng)計字典中相同的鍵對應的值的和


image.png

利用 defaultdict 設置默認值的方法 defaultdict(int)涡戳,代碼如下:

objs = [{'F29958SVDK6': 12}, {'F29958SVDK5': 12}, {'F29958SVDK6': 12}, {'F29958SVDK6': 12}, {'F29958SVDK6': 12}]
for obj in objs:
    for key, value in obj.items():
        d[key] += value
print(d)

print(defaultdict(int, {'F29958SVDK6': 60}))

二、collections 創(chuàng)建有序字典

字典dict是無序的脯倚,如果我們想要有序的dict渔彰,可以使用OrdereDict 。示例如下

from collections import OrderedDict

d = OrderedDict()

d['bar'] = 2
d['non'] = 8
d['sek'] = 5

print(d)
print(OrderedDict([('bar', 2), ('non', 8), ('sek', 5)]))

OrderedDict 內部維護著一個根據(jù)鍵插入順序排序的雙向鏈表推正。每次當一個新的元 素插入進來的時候恍涂,它會被放到鏈表的尾部。對于一個已經(jīng)存在的鍵的重復賦值不會 改變鍵的順序植榕。

需要注意的是再沧,一個 OrderedDict 的大小是一個普通字典的兩倍,因為它內部維 護著另外一個鏈表尊残。所以如果你要構建一個需要大量 OrderedDict 實例的數(shù)據(jù)結構的 時候 (比如讀取 100,000 行 CSV 數(shù)據(jù)到一個 OrderedDict 列表中去).

那么你就得仔細權衡一下是否使用 OrderedDict 帶來的好處要大過額外內存消耗的影響炒瘸。

2.1 改變 key-value 的順序

OrderedDict 是有序的字典,同時也能改變其順序寝衫。比如我們想要改變有序的 OrderedDict 對象的 key-value 順序顷扩,可以使用 move_to_end(key)。還是以上面創(chuàng)建的有序字典為例子

from collections import OrderedDict

d = OrderedDict()

d['bar'] = 2
d['non'] = 8
d['sek'] = 5
d.move_to_end("bar",last=False)
print(d)
print(OrderedDict([('bar', 2), ('non', 8), ('sek', 5)]))

可以看到之前排在第一位的 bar被移到最后一位了慰毅。move_to_end 還接收一個關鍵字參數(shù) last隘截。last 默認為 True,當 last = False 的時候,表示將該鍵移動到最前面技俐!

2.2 刪除 key_value

如果我們要刪除有序字典中的 key-value, 可以使用 popitem 方法乘陪, popitem(last=True) 按照先進后出的順序刪除 dict中 的 key-value,popitem(last=False) 按照先進先出的規(guī)則刪除 dict 中的 key-value雕擂。

print(OrderedDict([('bar', 2), ('non', 8), ('sek', 5)]))
d.popitem(last=False)
print(d)

三啡邑、字典排序

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

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

參數(shù)說明:
iterable -- 可迭代對象
key -- 主要是用來進行比較的元素井赌,只有一個參數(shù)谤逼,具體的函數(shù)的參數(shù)就是取自于可迭代對象中,指定可迭代對象中的一個元素來進行排序仇穗。
reverse -- 排序規(guī)則流部,reverse = True 降序 , reverse = False 升序(默認)纹坐。

3.1 按照 key 進行排序

理解了 sorted 函數(shù)就好辦了枝冀,代碼如下:

d = {'b':3,'a':4,'c':2,'d':1}
print(d.items())
print(sorted(d.items(), key=lambda i:i[0],reverse=True))
3.2 按照 value 進行排序
sorted(d.items(), key=lambda i:i[1])

結果:

[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

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

四果漾、通過某個關鍵字排序一個字典列表

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

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} ] 

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

通過使用 operator 模塊的 itemgetter 函數(shù)谷誓,可以非常容易的排序這樣的數(shù)據(jù)結構绒障,代碼如下:

from operator import itemgetter

rows_by_fname = sorted(rows, key=itemgetter('fname'))
print( rows_by_fname)

結果:

[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print( rows_by_uid)

結果:

[{'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() 函數(shù)也支持多個 keys,比如下面的代碼:

rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))
print( rows_by_fname)

結果:

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

好了捍歪,上面就是字典的一些高級用法户辱。
希望本文的內容對大家的學習或者工作能帶來一定的幫助,每天進步一點點糙臼,加油

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末庐镐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子弓摘,更是在濱河造成了極大的恐慌焚鹊,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件韧献,死亡現(xiàn)場離奇詭異末患,居然都是意外死亡,警方通過查閱死者的電腦和手機锤窑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門璧针,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渊啰,你說我怎么就攤上這事探橱∩暌伲” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵隧膏,是天一觀的道長哗讥。 經(jīng)常有香客問我,道長胞枕,這世上最難降的妖魔是什么杆煞? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮腐泻,結果婚禮上决乎,老公的妹妹穿的比我還像新娘。我一直安慰自己派桩,他們只是感情好构诚,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铆惑,像睡著了一般范嘱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸭津,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天彤侍,我揣著相機與錄音,去河邊找鬼逆趋。 笑死,一個胖子當著我的面吹牛晒奕,可吹牛的內容都是我干的闻书。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼脑慧,長吁一口氣:“原來是場噩夢啊……” “哼魄眉!你這毒婦竟也來了?” 一聲冷哼從身側響起闷袒,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤坑律,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后囊骤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晃择,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年也物,在試婚紗的時候發(fā)現(xiàn)自己被綠了宫屠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡滑蚯,死狀恐怖浪蹂,靈堂內的尸體忽然破棺而出抵栈,到底是詐尸還是另有隱情,我是刑警寧澤坤次,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布古劲,位于F島的核電站,受9級特大地震影響缰猴,放射性物質發(fā)生泄漏产艾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一洛波、第九天 我趴在偏房一處隱蔽的房頂上張望胰舆。 院中可真熱鬧,春花似錦蹬挤、人聲如沸缚窿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倦零。三九已至,卻和暖如春吨悍,著一層夾襖步出監(jiān)牢的瞬間扫茅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工育瓜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葫隙,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓躏仇,卻偏偏與公主長得像恋脚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子焰手,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345