Python 中的 Counter 模塊及使用詳解(搞定重復計數)
參考
項目 | 描述 |
---|---|
Python 標準庫 | DougHellmann 著 / 劉熾 等 譯 |
搜索引擎 | Bing |
Python 官方文檔 | collections — 容器數據類型 |
描述
項目 | 描述 |
---|---|
Python 解釋器 | 3.10.6 |
Counter 模塊
在 Python 的 collections 模塊中,有一個很常用的模塊就是 Counter。Counter 是一個簡單的計數器,用於統計某些可哈希對象的數量。它以字典的形式存儲元素和它們的計數。
Counter() 類
類 Counter() 能夠對傳入給該類的參數按照一定規則進行計數,並將計數對象與計數結果作為鍵值對以字典的形式進行結果的返回。
Counter(iterable=None, /, **kwds)
舉個栗子
from collections import Counter # 返回一個空的 Counter 對象 cnt = Counter() print(cnt) # 將可迭代對象(字符串)作為參數 cnt = Counter('Hello World') print(cnt) # 將可迭代對象(列表)作為參數 cnt = Counter(['a', 'a', 'b', 'd', 'c', 'd']) print(cnt) # 使用可迭代對象(字典)作為參數 cnt = Counter({'a': 1, 'b': 2, 'd': 3, 'c': 2}) print(cnt) # 使用關鍵字參數 cnt = Counter(a=1, b=2, d=3, c=2) print(cnt)
執行效果
Counter()
Counter({'l': 3, 'o': 2, 'H': 1, 'e': 1, ' ': 1, 'W': 1, 'r': 1, 'd': 1})
Counter({'a': 2, 'd': 2, 'b': 1, 'c': 1})
Counter({'d': 3, 'b': 2, 'c': 2, 'a': 1})
Counter({'d': 3, 'b': 2, 'c': 2, 'a': 1})
Counter() 對象
字典
由 Counter() 返回的結果為一個字典,它擁有普通字典的大部分方法。在大多數情況下,你可以像操作字典一樣操作 Counter 對象。對此,請參考如下示例:
from collections import Counter cnt = Counter('Hello World') print(cnt) # 輸出 Counter 對象中的鍵值對列表 print(cnt.items()) # 移除 Counter 對象中的最後一個鍵值對 print(cnt.popitem()) print(cnt) # 輸出 Counter 中鍵 l 對應的值 print(cnt['l'])
執行結果
Counter({'l': 3, 'o': 2, 'H': 1, 'e': 1, ' ': 1, 'W': 1, 'r': 1, 'd': 1})
dict_items([('H', 1), ('e', 1), ('l', 3), ('o', 2), (' ', 1), ('W', 1), ('r', 1), ('d', 1)])
('d', 1)
Counter({'l': 3, 'o': 2, 'H': 1, 'e': 1, ' ': 1, 'W': 1, 'r': 1})
3
有序性
Python 中的字典是無序的,無序的 的含義並不是說字典中的鍵值對沒有順序,而是指字典中的鍵值對的順序是不可預測的。對此,請參考如下示例:
d = {'a': 1, 'b': 2, 'c': 3} for key in d: print(key)
該示例的輸出結果可能是:
a
b
c
也可能是:
b
c
a
當然還存在其他可能,這裡就不一一列舉瞭。
Python 官方對 Python 3.6 版本中的字典進行瞭優化,使其能夠記住鍵值對插入的順序。此後,字典顯得不那麼凌亂瞭(字典中的鍵值對的順序變得可以預測瞭)。
KeyError
在 Python 的內置字典中,若嘗試訪問不存在的鍵,Python 將拋出 KeyError 異常錯誤。對此,請參考如下示例:
d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d) # 嘗試訪問字典 d 中不存在的鍵 print(d['d'])
執行效果
Traceback (most recent call last):
File "C:\main.py", line 5, in <module>
print(d['d'])
KeyError: 'd'
{'a': 1, 'b': 2, 'c': 3}
同樣的場景。這一次,我們讓 Counter 作為主角。
from collections import Counter cnt = Counter({'a': 1, 'b': 2, 'c': 3}) print(cnt) # 嘗試訪問 Counter 中不存在的鍵 print(cnt['d'])
執行效果
訪問 Counter 對象中不存在的鍵時,並不會拋出 KeyError 異常,而是返回默認計數值 0。
Counter({'c': 3, 'b': 2, 'a': 1})
0
魔術方法 __missing__
__missing__() 是 Python 中的一個特殊方法,用於處理通過鍵訪問字典中的值時鍵不存在時的情況。
當我們使用字典的索引來訪問一個不存在的鍵時,Python 將會調用特殊方法 __missing__() 來嘗試返回一個合適的值。若未實現 __missing__() 方法,Python 將會拋出 KeyError 異常。對此,請參考如下示例:
# 創建一個字典對象,該對象繼承自 Python 內置的 dict 對象 class MyDict(dict): def __missing__(self, key): return 0 # 實例化 MyDict() 對象 myDict = MyDict() # 嘗試訪問 myDict 對象中不存在的鍵 a print(myDict['a'])
執行效果
0
update() 方法
Counter 對象與 dict 對象同樣實現瞭 update() 方法。使用 update() 方法能夠將作為參數的字典合並到調用該方法的 dict 對象中。不同的是,dict 對象的 update() 方法在遇到具有相同的鍵時,將會對該鍵對應的值執行 覆蓋 操作。而 Counter 對象的 update() 方法在遇到具有相同的鍵時,將會對該鍵對應的值執行 疊加 操作。對此,請參考如下示例:
from collections import Counter # Python 中內置的 dict 對象 d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d) d.update({'a': 4}) print(d) print() # Counter 對象 cnt = Counter({'a': 1, 'b': 2, 'c': 3}) print(cnt) cnt.update({'a': 4}) print(cnt)
執行效果
{'a': 1, 'b': 2, 'c': 3}
{'a': 4, 'b': 2, 'c': 3}Counter({'c': 3, 'b': 2, 'a': 1})
Counter({'a': 5, 'c': 3, 'b': 2})
Counter 對象的常用方法
most_common()
most_common() 方法將返回一個列表,列表中的元素均為 Counter 對象中的鍵值對組成的元組。元組在列表中的順序取決於計數值(鍵值對中的值)的大小。計數值更大的元組將位於列表的前端,計數值相等的元組將按照它們首次在列表中出現的順序進行排列(先出現的元組將更靠近列表的前端)。
most_common() 默認將使用 Counter 對象中所有的鍵值對組成的元組作為返回列表中的元素。你可以通過向該方法提供一個數值,該數值將指定放回的列表中的元素的數量。
舉個栗子
from collections import Counter cnt = Counter({'a': 1, 'b': 2, 'c': 3}) print(cnt) print() print(cnt.most_common()) # 返回由 Counter 中計數值最大的兩個 # 鍵值對構成的元組所組成的列表 print(cnt.most_common(2)) # 返回由 Counter 中計數值最大的 # 鍵值對構成的元組所組成的列表 print(cnt.most_common(1))
執行效果
Counter({'c': 3, 'b': 2, 'a': 1})
[('c', 3), ('b', 2), ('a', 1)]
[('c', 3), ('b', 2)]
[('c', 3)]
elements()
elements() 方法將返回一個以 Counter 對象中的鍵為元素的迭代器,其中每個元素將重復出現計數值所指定的次數。
迭代器中的元素將存在如下特點:
- 元素將會按照其首次添加到 Counter 對象中的順序進行返回。
- 某個鍵對應的計數值小於一,那麼該鍵將不會作為元素出現在 element() 方法返回的迭代器中。
舉個栗子
from collections import Counter cnt = Counter({'a': 1, 'b': 2, 'c': 3, 'd': -4}) print(cnt) print() print(list(cnt.elements()))
執行效果
Counter({'c': 3, 'b': 2, 'a': 1, 'd': -4})
['a', 'b', 'b', 'c', 'c', 'c']
total()
total() 方法將返回 Counter 對象中,所有計數值累加後得到的結果。對此,請參考如下示例:
from collections import Counter cnt = Counter({'a': 1, 'b': 2, 'c': 3, 'd': -4}) cnt1 = Counter('Hello World') print(cnt.total()) print(cnt1.total())
執行效果
2
11
subtract()
該方法的效果與 Counter 對象的 update() 方法類似。如果說 update() 方法執行的是 加 操作,那麼 subtract() 方法執行的則是 減 操作。對此,請參考如下示例:
from collections import Counter cnt = Counter({'a': 1, 'b': 2, 'c': 3, 'd': -4}) cnt.subtract({'a': 0, 'b': 1, 'd': -11}) print(cnt)
執行效果
Counter({'d': 7, 'c': 3, 'a': 1, 'b': 1})
Counter 對象間的運算
註:
本部分內容中講解到的運算符僅能在 Python 3.3 及以後版本中正常使用。
加法運算
在 Python 的 Counter 模塊中,兩個 Counter 對象可以相加,相加後將返回一個新的 Counter 對象,其中每個元素的計數是兩個原始 Counter 對象中該元素計數的總和。可以通過使用加法運算符來執行此操作。對此,請參考如下示例:
from collections import Counter cnt = Counter('Hello') cnt1 = Counter('World') print(cnt) print(cnt1) print(cnt + cnt1)
執行效果
Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1})
Counter({'W': 1, 'o': 1, 'r': 1, 'l': 1, 'd': 1})
Counter({'l': 3, 'o': 2, 'H': 1, 'e': 1, 'W': 1, 'r': 1, 'd': 1})
註:
在 Counter 對象間的運算過程中,對於 Counter 中不存在的鍵,其計數值為零。
減法運算
在 Python 的 Counter 模塊中,可以使用減法運算符來對兩個 Counter 對象進行減法運算,即將左側 Counter 對象中的計數器值減去右側 Counter 對象中相同鍵的計數器值,最後返回一個新的 Counter 對象。對此,請參考如下示例:
from collections import Counter cnt = Counter('cook') cnt1 = Counter('coder') print(cnt) print(cnt1) print(cnt - cnt1)
執行效果
Counter({'o': 2, 'c': 1, 'k': 1})
Counter({'c': 1, 'o': 1, 'd': 1, 'e': 1, 'r': 1})
Counter({'o': 1, 'k': 1})
註:
在 Counter 對象間的運算過程中,對於 Counter 中不存在的鍵,其計數值為零。
並集運算
Counter 對象之間的並集運算是指兩個 Counter 對象按照鍵的並集進行運算,返回的結果是一個新的 Counter 對象,其中包含的鍵和值均為 原始 Counter 對象中存在的鍵及其對應的最大值。對此,請參考如下示例:
from collections import Counter cnt = Counter('Hello') cnt1 = Counter('World') print(cnt) print(cnt1) print(cnt | cnt1)
執行效果
Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1})
Counter({'W': 1, 'o': 1, 'r': 1, 'l': 1, 'd': 1})
Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1, 'W': 1, 'r': 1, 'd': 1})
交集運算
Counter 對象之間的交集運算是指兩個 Counter 對象按照鍵的交集進行運算,返回的結果是一個新的 Counter 對象,其中包含的鍵和值均為 原始 Counter 對象中共同擁有的鍵及其對應的最小值。對此,請參考如下示例:
from collections import Counter cnt = Counter('Hello') cnt1 = Counter('World') print(cnt) print(cnt1) print(cnt & cnt1)
執行效果
Counter({'l': 2, 'H': 1, 'e': 1, 'o': 1})
Counter({'W': 1, 'o': 1, 'r': 1, 'l': 1, 'd': 1})
Counter({'l': 1, 'o': 1})
單目運算
單目運算指的是表達式中存在單目運算符的運算操作。存在兩種單目運算符,即單目減法運算符與單目加法運算符。無論是單目減法運算符還是單目加法運算符,它們的操作對象均為 Counter 對象中的計數值。
在對 Counter 對象進行單目運算後,將返回一個由大於零的計數值相關的鍵值對組成的 Counter 對象。對此,請參考如下示例:
from collections import Counter cnt = Counter({'a': 4, 'b': 3, 'd': 0, 'c': -5}) print(+cnt) print(-cnt)
執行效果
Counter({'a': 4, 'b': 3})
Counter({'c': 5})
Counter 對象間的比較
從 Python 3.10 版本開始,Counter 對象間開始支持常見的比較運算符,這些運算符有:
- <
- <=
- >
- >=
- ==
- !=
這裡以 > 及 == 為例進行講解。
>
當 > 的左側的 Counter 對象的鍵對應的計數值均大於該符號右側的 Counter 對象中相同的鍵(對於 Counter 中不存在的鍵,其計數值為零)對應的計數值時,比較結果為 True。否則為 False。對此,請參考如下示例:
from collections import Counter cnt = Counter({'a': 4, 'b': 3, 'd': 7, 'c': 5}) cnt1 = Counter({'c': 3, 'd': 2, 'b': 6, 'a': 4}) cnt2 = Counter({'c': 4, 'd': 6, 'b': 2, 'a': 3}) print(cnt > cnt1) print(cnt > cnt2)
執行效果
False
True
==
當 == 的左側的 Counter 對象的鍵對應的計數值均等於該符號右側的 Counter 對象中相同的鍵(對於 Counter 中不存在的鍵,其計數值為零)對應的計數值時,比較結果為 True。否則為 False。對此,請參考如下示例:
from collections import Counter cnt = Counter({'a': 3, 'b': 2, 'd': 6, 'c': 4}) cnt1 = Counter({'c': 3, 'd': 2, 'b': 6, 'a': 4}) cnt2 = Counter({'c': 4, 'd': 6, 'b': 2, 'a': 3}) print(cnt == cnt1) print(cnt == cnt2)
執行效果
False
True
到此這篇關於Python 中的 Counter 模塊及使用詳解(搞定重復計數)的文章就介紹到這瞭,更多相關Python Counter 模塊內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python中collections.Counter()的具體使用
- 5種Python統計次數方法技巧
- Python中最神秘missing()函數介紹
- 圖文詳解Python中最神秘的一個魔法函數
- Python的collections模塊真的很好用