defaultdict引入
現在假設這樣一種情況,有一組清單字元串。我們需要統計每個字元串出現的次數,并以鍵值對的形式儲存起來。下面先來示範一個錯誤的寫法。
a = ['a','b','r','a','d','r']
b = {}
for i in a:
b[i] += 1
print(b)
Traceback (most recent call last):
File "D:/Spider_base/test.py", line 5, in <module>
b[i] += 1
KeyError: 'a'
報錯的原因是,字典對于不存在key直接取值的話,會顯示KeyError。如果不想報錯,我們就需要加上一個判斷,對于不存在的key,我們就加上,并賦予初值為1。如下:
a = ['a','b','r','a','d','r']
b = {}
for i in a:
if i in b.keys():
b[i] += 1
else:
b[i] = 1
print(b)
{'a': 2, 'b': 1, 'r': 2, 'd': 1}
對于上述代碼,我們還可以進行優化,即使用字典的setdefault來代替if語句。對于不存在的key賦予預設值0,存在的key就不做任何操作。
a = ['a','b','r','a','d','r']
b = {}
for i in a:
b.setdefault(i,0)
b[i] += 1
print(b)
{'a': 2, 'b': 1, 'r': 2, 'd': 1}
問題來了,我們還可以再優化嗎?上一次優化雖然去除了if語句,但對于每一個key,我們都需要進行判斷是否需要給一個預設值。
defaultdict
答案是可以再次優化,python提供了一種預設值字典的資料結構。它允許我們在定義字典時給所有不存在的key設定預設值,這樣當取不存在的key時,就不會報錯。
from collections import defaultdict
a = ['a','b','r','a','d','r']
b = defaultdict(int)
for i in a:
b[i] += 1
print(b)
defaultdict(<class 'int'>, {'a': 2, 'b': 1, 'r': 2, 'd': 1})
defaultdict字典相當于是普通字段的強化版,繼承原始dict的功能,并賦予了它新的特性。
初始化defaultdict的參數是一個可調用對象,即函數名。int函數就相當于函數如下:
def fun():
return 0
也可以使用匿名函數如下:
b = defaultdict(lambda :0)
也可以使用:list對應[ ],str對應的是空字元串,set對應set( ),int對應0
OrderedDict
使用
dict
時,Key是無序的。在對
dict
做疊代時,我們無法确定Key的順序。如果要保持Key的順序,可以用
OrderedDict。
from collections import OrderedDict
a = OrderedDict()
print(a.fromkeys(['a','b','d','c'],'qq'))
OrderedDict([('a', 'qq'), ('b', 'qq'), ('d', 'qq'), ('c', 'qq')])
OrderedDict
的Key會按照插入的順序排列,不是Key本身排序。
Counter
Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素作為key,其計數作為value。計數值可以是任意的Interger(包括0和負數)。
- 建立
from collections import Counter
a = Counter()
b = Counter('afdasfdasd')
c = Counter({'a':4,'b':7})
d = Counter(a=4,b=7)
print(a,b,c,d)
Counter() Counter({'a': 3, 'd': 3, 'f': 2, 's': 2}) Counter({'b': 7, 'a': 4}) Counter({'b': 7, 'a': 4})
建立的方式有三種,第一種是空的Counter類,第二種傳入一個可疊代對象,可以是str、list、tuple、dict,最後一種是以鍵值對的形式。
- 通路
因為最後的計數結果是一個字典的樣式,故通路通過通路字典的方式,但若查找的key不存在将會報錯。
- most_common([n])
該函數是将計數結果以清單嵌套二進制元組的形式傳回。參數n表示給最多n個元素計數,且計數量大的優先,預設傳回所有計數。
from collections import Counter
b = Counter('afdasfdasd')
print(b)
print(b.most_common())
print(b.most_common(2))
Counter({'a': 3, 'd': 3, 'f': 2, 's': 2})
[('a', 3), ('d', 3), ('f', 2), ('s', 2)]
[('a', 3), ('d', 3)]