【Python】详解 collections.Counter
目錄
一、緒論
二、Counter 類
2.1 創建 Counter 對象
2.2 數值訪問(鍵-值索引)
2.3 元素刪除 (鍵-值對刪除)
2.4 update() / subtract() ——?元素更新 (鍵-值對增減)
2.5 elements()?——?元素全部列出
2.6?most_common()?—— 元素按出現頻數從大到小列出
2.7?算術與集合運算
2.8 常用操作范例
一、緒論
collections 作為 Python 的內建集合模塊,實現了許多十分高效的特殊容器數據類型,即除了 Python 通用內置容器: dict、list、set 和 tuple 等的替代方案。在?IDLE 輸入 help(collections) 可查看幫助文檔,其中常見的類/函數如下:
| 名稱 | 功能 |
| namedtuple | 用于創建具有命名字段的 tuple 子類的 factory 函數 (具名元組) |
| deque | 類似 list 的容器,兩端都能實現快速 append 和 pop (雙端隊列) |
| ChainMap | 類似 dict 的類,用于創建多個映射的單視圖 |
| Counter | 用于計算 hashable 對象的 dict 子類 (可哈希對象計數) |
| OrderedDict | 記住元素添加順序的 dict 子類 (有序字典) |
| defaultdict | dict 子類調用 factory 函數來提供缺失值 |
| UserDict | 包裝 dict 對象以便于 dict 的子類化 |
| UserList | 包裝 list 對象以便于 list 的子類化 |
| UserString | 包裝 string 對象以便于 string 的子類化 |
而本文詳述的對象為 hashable 對象計數器 —— Counter 。
二、Counter 類
Counter,顧名思義是一個?計數器。Counter 類作為一個無序的容器類型,以字典的 key-value 對形式存儲元素,旨在統計各元素 (哈希項) 出現的次數。具體而言,key 表示元素,value 表示各元素 key 出現的次數,可為任意整數 (即包括0與負數)。Counter 類有時被稱為?bags 或 multisets 。我們在 IDLE 通過 help(collections.Counter) 可查看幫助文檔。
在 Python 3.7 版更新后,作為 dict?的子類,Counter 繼承了記住插入順序的功能。?Counter 對象進行數學運算時同樣會保持順序。 結果會先按每個元素在運算符左邊的出現時間排序,然后再按其在運算符右邊的出現時間排序。
2.1 創建 Counter 對象
實例化 Counter 的常見方式為:
## 導入 Counter 類 >>> from collections import Counter # class collections.Counter([iterable-or-mapping])>>> hashmap1 = Counter() # a new, empty counter >>> hashmap1 Counter()## 通過可迭代對象、映射和關鍵字參數等實例化 Counter 對象 >>> hashmap2 = Counter('happy') # a new counter from an iterable >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})>>> hashmap3 = Counter(['A', 'A', 'K', 4, 7, 7]) # a new counter from an iterable >>> hashmap3 Counter({'A': 2, 'K': 1, 4: 1, 7: 2})>>> hashmap4 = Counter(('M', 'M', 4, 'A', 1, 1)) # a new counter from an iterable >>> hashmap4 Counter({'M': 2, 4: 1, 'A': 1, 1: 2})>>> hashmap5 = Counter({'x':1, 'y':2}) # a new counter from a mapping >>> hashmap5 Counter({'y': 2, 'x': 1})>>> hashmap6 = Counter(kangkang=1, daming=2, sam=3) # a new counter from keyword args >>> hashmap6 Counter({'sam': 3, 'daming': 2, 'kangkang': 1})# 類型檢查 >>> type(hashmap1), type(hashmap2), type(hashmap3), type(hashmap4), type(hashmap5), type(hashmap6) (<class 'collections.Counter'>, <class 'collections.Counter'>, <class 'collections.Counter'>, <class 'collections.Counter'>, <class 'collections.Counter'>), <class 'collections.Counter'>)可見元素從一個?iterable?被計數或從其他的?mapping?(or counter) 實現初始化。
2.2 數值訪問(鍵-值索引)
Counter 對象類似于 dict 接口,也通過 key 索引訪問 value,但注意返回的 value 表示的是 key 的計數值:
>>> hashmap2['p'] # hashmap2 = Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1}) 2>>> hashmap3['A'] # hashmap3 = Counter({'A': 2, 'K': 1, 4: 1, 7: 2}) 2>>> hashmap4['M'] # hashmap4 = Counter({'M': 2, 4: 1, 'A': 1, 1: 2}) 2>>> hashmap5['x'] # hashmap5 = Counter({'y': 2, 'x': 1}) 1而當訪問的 key 不存在時,返回 0 而非 KeyError:
# count of a missing element is zero >>> hashmap2[6] # hashmap2 = Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1}) 0 >>> hashmap3[6] # hashmap3 = Counter({'A': 2, 7: 2, 'K': 1, 4: 1}) 0 >>> hashmap4[6] # hashmap4 = Counter({'M': 2, 1: 2, 4: 1, 'A': 1}) 0 >>> hashmap5[6] # hashmap5 = Counter({'y': 2, 'x': 1}) 0作為 dict 的子類,通過 Counter.keys()、Counter.values()、Counter.items() 訪問鍵-值對仍然適用:
# 以 hashmap2 為例 >>> hashmap2 = Counter('happy') >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})>>> hashmap2.keys() dict_keys(['h', 'a', 'p', 'y']) >>> type(hashmap2.keys()) <class 'dict_keys'>>>> hashmap2.values() dict_values([1, 1, 2, 1]) >>> type(hashmap2.values()) <class 'dict_values'>>>> hashmap2.items() dict_items([('h', 1), ('a', 1), ('p', 2), ('y', 1)]) >>> type(hashmap2.items()) <class 'dict_items'>注意,原地操作如 hashmap[key] += 1,值類型只支持加和減,故分數、小數、十進制甚至負值都適用。
2.3 元素刪除 (鍵-值對刪除)
對于 Counter 對象的元素刪除應使用內置函數 del,而令 value=0 是不能刪除元素(鍵-值對)的。
# 以 hashmap2 為例 >>> hashmap2 = Counter('happy') >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})>>> hashmap2['y'] = 0 >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 0}) # 'y' 還在, 只是 value=0 而已>>> del hashmap2['y'] >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1}) # 'y' 被刪除了2.4 update() / subtract() ——?元素更新 (鍵-值對增減)
可以使用另外的?iterable 對象或 Counter 對象實現對原 Counter 對象的元素更新 (鍵-值對增減)。
其中,元素增加使用 Counter.update(iterable-or-mapping) 方法:
## 以 hashmap2 為例, 其余同理 >>> hashmap2 = Counter('happy') >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})## 用 iterable 對象更新 >>> hashmap2.update('hp') # 用 string 更新 (iterable 對象) >>> hashmap2 Counter({'p': 3, 'h': 2, 'a': 1, 'y': 1}) >>> hashmap2.update(['a','y']) # 用 list 更新 (iterable 對象) >>> hashmap2 Counter({'p': 3, 'h': 2, 'a': 2, 'y': 2})>>> hashmap2.update(('a')) # 用 tuple 更新 (iterable 對象) >>> hashmap2 Counter({'a': 3, 'p': 3, 'h': 2, 'y': 2})## 用 mapping 對象更新 >>> hashmap2.update({'h':1, 'y':1}) # 用 dict 更新 (mapping 對象) >>> hashmap2 Counter({'h': 3, 'a': 3, 'p': 3, 'y': 3})## 用 Counter 對象更新 >>> hashmap2.update(Counter('hapy')) >>> hashmap2 Counter({'h': 4, 'a': 4, 'p': 4, 'y': 4})注意,元素的添加來自 iterable 對象計數元素,或另一個 mapping 對象?(或 Counter 對象) ,其中 iterable 對象應為序列 sequence 元素。
同理,元素減少使用 Counter.subtract(iterable-or-mapping) 方法,但注意元素的計數 —— value 為 0 和 負數都是允許的:
# 以 hashmap2 為例, 其余同理 >>> hashmap2 = Counter('happy') >>> hashmap2 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})# 用 iterable 對象更新元素 >>> hashmap2.subtract('p') # 用 string 更新 >>> hashmap2 Counter({'h': 1, 'a': 1, 'p': 1, 'y': 1}) >>> hashmap2.subtract(['p']) # 用 list 更新 >>> hashmap2 Counter({'h': 1, 'a': 1, 'p': 0, 'y': 1}) # 允許 value <= 0>>> hashmap2.subtract(('p')) # 用 tuple 更新 >>> hashmap2 Counter({'h': 1, 'a': 1, 'y': 1, 'p': -1}) # 允許 value <= 0## 用 mapping 對象更新 >>> hashmap2.subtract({'h':2}) # 用 dict 更新 >>> hashmap2 Counter({'a': 1, 'y': 1, 'h': -1, 'p': -1}) # 允許 value <= 0## 用 Counter 對象更新 >>> hashmap2.update(Counter('ay')) >>> hashmap2 Counter({'a': 0, 'y': 0, 'h': -1, 'p': -1})可見使用 iterable 對象更新原 Counter 對象之前,都會被隱式地轉換為 Counter 對象,再把元素更新到原 Counter 對象上。
2.5 elements()?——?元素全部列出
Counter.elements() 方法將返回一個迭代器。元素的計數有多少,在該迭代器中就包含多少個該元素。元素排列無確定順序 元素按首次出現的順序返回,且不含 value<= 0 的元素。
>>> hashmap7 = Counter('happy') >>> hashmap7 Counter({'p': 2, 'h': 1, 'a': 1, 'y': 1})>>> hashmap7.elements() # 返回迭代器 <itertools.chain object at 0x00000249719226A0>>>> list(hashmap7.elements()) # 顯式類型轉換 ['h', 'a', 'p', 'p', 'y']>>> tuple(hashmap7.elements()) # 顯式類型轉換 ('h', 'a', 'p', 'p', 'y')>>> str(hashmap7.elements()) # 那是不可能的... '<itertools.chain object at 0x0000024971125390>'>>> sorted(hashmap7.elements()) # 隱式類型轉換 ['a', 'h', 'p', 'p', 'y']2.6?most_common()?—— 元素按出現頻數從大到小列出
Counter.most_common([n]) 方法將返回一個 list,其中包含前?n?個出現頻數最高的元素及其出現次數,并從大到小排列。 若?n?被省略或為 None,most_common() ?將返回 Counter 對象中的所有元素。若元素計數值相等,則按首次出現的順序排序:
>>> hashmap8 = Counter(x=3, y=2, z=1, h=2) >>> hashmap8 Counter({'x': 3, 'y': 2, 'h': 2, 'z': 1})>>> hashmap8.most_common(1) # n=1 [('x', 3)] >>> hashmap8.most_common(2) # n=2 [('x', 3), ('y', 2)] >>> hashmap8.most_common(3) # n=3 [('x', 3), ('y', 2), ('h', 2)] >>> hashmap8.most_common(4) # n=4 [('x', 3), ('y', 2), ('h', 2), ('z', 1)] # 'y' 與 'h' 出現頻次均為 2, 但 'y' 先出現, 故前排>>> hashmap8.most_common() # n ignored [('x', 3), ('y', 2), ('h', 2), ('z', 1)] # 全排:從大到小 >>> hashmap8.most_common()[::-1] # n ignored [('z', 1), ('h', 2), ('y', 2), ('x', 3)] # 全排:從小到大2.7?算術與集合運算
有幾個常用的數學運算操作:
>>> h1 = Counter(x=1, y=2) >>> h2 = Counter(x=2, y=1) >>> h3 = Counter(x=1, y=-1)>>> h1 + h2 Counter({'x': 3, 'y': 3}) # 按元素相加 >>> h2 + h3 Counter({'x': 3}) # value <= 0 的會被刪除>>> h1 - h2 Counter({'y': 1}) # 按元素相減 >>> h1 - h3 Counter({'y': 3}) # value <= 0 的會被刪除>>> h1 & h2 Counter({'x': 1, 'y': 1}) # 按元素取 min() (交集)>>> h1 | h2 Counter({'x': 2, 'y': 2}) # 按元素取 max() (并集)? ? ? ? 還有單目加和減 (一元操作符) 及其等價形式:
>>> hashmap9 = Counter(a=2, b=1, c=0, d=-1)>>> +hashmap9 Counter({'a': 2, 'b': 1}) # 去除 value<=0 的元素>>> -hashmap9 Counter({'d': 1}) # 去除 value>=0 的元素>>> hashmap9 += Counter() >>> hashmap9 Counter({'a': 2, 'b': 1}) # 去除 value<=0 的元素2.8 常用操作范例
>>> hashmap8 = Counter(x=3, y=2, z=1, h=2) >>> hashmap8 Counter({'x': 3, 'y': 2, 'h': 2, 'z': 1})## 對 Counter 對象的 value 求和 >>> sum(hashmap8.values()) 8## 從小到大排序 >>> hashmap8.most_common()[::-1] [('z', 1), ('h', 2), ('y', 2), ('x', 3)] ## 類型轉換 >>> list(hashmap8) ['x', 'y', 'z', 'h'] # 將 Counter 對象的 key 轉換為 list >>> tuple(hashmap8) ('x', 'y', 'z', 'h') # 將 Counter 對象的 key 轉換為 tuple >>> set(hashmap8) {'z', 'y', 'x', 'h'} # 將 Counter 對象的 key 轉換為 set >>> dict(hashmap8) {'x': 3, 'y': 2, 'z': 1, 'h': 2} # 將 Counter 對象的轉換為 dict## 去除 value <= 0 的元素 >>> hashmap9 = Counter(a=2, b=1, c=0, d=-1) >>> hashmap9 Counter({'a': 2, 'b': 1, 'c': 0, 'd': -1})>>> hashmap9 += Counter() >>> hashmap9 Counter({'a': 2, 'b': 1})參考文獻
《Python Immediate》
collections --- 容器數據類型 — Python 3.10.4 文檔
collections - 廖雪峰的官方網站
總結
以上是生活随笔為你收集整理的【Python】详解 collections.Counter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: amoeba启动报错
- 下一篇: Maya2011下载 (破解正式版)