
作者:梁唐
來源:早起Python
大家好,今天為大家介紹python當中一個很好用也是很基礎的工具庫,叫做collections。collection在英文當中有容器的意思,所以顧名思義,這是一個容器的集合。這個庫當中的容器很多,有一些不是很常用,本篇文章選擇了其中最常用的幾個,一起介紹給大家。
defaultdict
defaultdict可以說是這個庫當中使用最簡單的一個,并且它的定義也很簡單,我們從名稱基本上就能看得出來。它解決的是我們使用dict當中最常見的問題,就是key為空的情況。
在正常情況下,我們在dict中獲取元素的時候,都需要考慮key為空的情況。如果不考慮這點,那么當我們獲取了一個不存在的key,會導致系統拋出異常。我們當然可以在每次get之前寫一個if判斷,但是這很麻煩,比如:
if key in dict: return dict[key] else: return None
當然,這是最笨的方法,dict當中為我們提供了帶默認值的get方法。比如,我們可以寫成:
return dict.get(key, None)
這樣,當key不在dict當中存在的時候,會自動返回我們設置的默認值。這個省去了很多麻煩的判斷,但是在一些特殊情況下仍然存在一點問題。舉個例子,比如當key存在重復,我們希望將key相同的value存進一個list當中,而不是只保留一個。這種情況下寫成代碼就會比較復雜:
data = [(1, 3), (2, 1), (1, 4), (2, 5), (3, 7)] d = {} for k, v in data: if k in d: d[k].append(v) else: d[k] = [v]
由于dict的value是一個list,所以我們還是需要判斷是否為空,不能直接使用默認值,間接操作當然可以,但是還是不夠簡單:
for k, v in data: cur = d.get(k, []) cur.append(v) d[k] = v
這和使用if區別并不大,為了完美解決這個問題,我們可以使用collections當中的defaultdict:
from collections import defaultdict d = defaultdict(list) for k, v in data: d[k].append(v)
使用defaultdict之后,如果key不存在,容器會自動返回我們預先設置的默認值。需要注意的是defaultdict傳入的默認值可以是一個類型也可以是一個方法。如果我們傳入int,那么默認值會被設置成int()的結果,也就是0,如果我們想要自定義或者修改,我們可以傳入一個方法,比如:
d = defaultdict(lambda: 3) for k, v in data: d[k] += v
Counter
這是一個非常常用和非常強大的工具,我們經常用到。
在我們實際的編程當中,我們經常遇到一個問題,就是數數和排序。比如說我們在分析文本的時候,會得到一堆單詞。其中可能有大量的長尾詞,在整個文本當中可能只出現過寥寥幾次。于是我們希望計算一下這些單詞出現過的數量,只保留出現次數最高的若干個。
這個需求讓我們自己實現當然也不困難,我們完全可以創建一個dict,然后對這些單詞一個一個遍歷。原本我們還需要考慮單詞之前沒有出現過的情況,如果我們上面說的defaultdict,又要簡單許多。但是我們還是少不了計數然后排序的步驟,如果使用Counter這個步驟會縮減成一行代碼。
舉個例子:
words = ['apple', 'apple', 'pear', 'watermelon', 'pear', 'peach'] from collections import Counter counter = Counter(words) >>> print(counter) Counter({'apple': 2, 'pear': 2, 'watermelon': 1, 'peach': 1})
我們直接將一個list傳入Counter中作為參數,它會自動為我們替當中的每個元素計數。
如果我們要篩選topK,也非常簡單,它為我們提供了most_common方法,我們只需要傳入需要求的K即可:
counter.most_common(1) [('apple', 2)]
除此之外,它的構造函數還接收dict類型。我們可以直接通過一個value是int類型的dict來初始化一個Counter,比如:
c = Counter({'apple': 5, 'pear': 4}) c = Counter(apple=4, pear=3)
并且,它還支持加減法的操作,比如我們可以將兩個Counter相加,它會自動將兩個Counter合并,相同的key對應的value累加。相減也是同理,會將能對應的value做減法,被減的key對應不上的會保留,而減數中對應不上的key則會被丟棄。并且需要注意,Counter支持value為負數。
deque
我們都知道queue是隊列,deque也是隊列,不過稍稍特殊一些,是雙端隊列。對于queue來說,只允許在隊尾插入元素,在隊首彈出元素。而deque既然稱為雙端隊列,那么說明它的隊首和隊尾都支持元素的插入和彈出。相比于普通的隊列,要更加靈活一些。
除了常用的clear、copy、count、extend等api之外,deque當中最常用也是最核心的api還有append、pop、appendleft和popleft。從名字上我們就看得出來,append和pop和list的append和pop一樣,而appendleft和popleft則是在隊列左側,也就是頭部進行pop和append的操作。非常容易理解。
在日常的使用當中,真正用到雙端隊列的算法其實不太多。大多數情況下我們使用deque主要有兩個原因,第一個原因是deque收到GIL的管理,它是線程安全的。而list則沒有GIL鎖,因此不是線程安全的。也就是說在并發場景下,list可能會導致一致性問題,而deque不會。另一個原因是deque支持固定長度,當長度滿了之后,當我們繼續append時,它會自動彈出最早插入的數據。
比如說當我們擁有海量的數據,我們不知道它的數量,但是想要保留最后出現的指定數量的數據的時候,就可以使用deque。
from collections import deque dque = deque(maxlen=10) # 假設我們想要從文件當中獲取最后10條數據 for i in f.read(): dque.append(i)
namedtuple
namedtuple很特殊,它涉及到元編程的概念。簡單介紹一下元編程的概念,我們不做過多的深入。簡而言之,就是在常見的面向對象當中。我們都是定義類,然后通過類的構造函數來創建實例。而元編程指的是我們定義元類,根據元類創建出來的并不是一個實例,而是一個類。如果用模具和成品來分別比喻類和實例的話,元類相當于是模具的模具。
namedtuple是一個非常簡單的元類,通過它我們可以非常方便地定義我們想要的類。
它的用法很簡單,我們直接來看例子。比如如果我們想要定義一個學生類,這個類當中有name、score、age這三個字段,那么這個類會寫成:
class Student: def __init__(self, name=None, score=None, age=None): self.name = name self.score = score self.age = age
這還只是粗略的寫法,如果考慮規范,還需要定義property等注解,又需要很多代碼。如果我們使用namedtuple可以簡化這個工作,我們來看代碼:
from collections import namedtuple # 這個是類,columns也可以寫成'name score age',即用空格分開 Student = namedtuple('Student', ['name', 'score', 'age']) # 這個是實例 student = Student(name='xiaoming', score=99, age=10) print(student.name)
通過使用namedtuple,我們只需要一行就定義了一個類,但是這樣定義的類是沒有缺失值的,但是namedtuple很強大,我們可以通過傳入defaults參數來定義缺失值。
Student = namedtuple('Student', ['name', 'score', 'age'], defaults=(0, 0))
可以注意到,雖然我們定義了三個字段,但是我們只設置了兩個缺失值。在這種情況下,namedtuple會自動將缺失值匹配上score和age兩個字段。因為在Python的規范當中,必選參數一定在可選參數前面。所以nuamdtuple會自動右對齊。
細數一下,我們今天的文章當中介紹了defaultdict、Counter、deque和namedtuple這四種數據結構的用法。除了這四個之外,collections庫當中還有一些其他的工具類,只是我們用的頻率稍稍低一些,加上由于篇幅的原因,這里就不多做贅述了。感興趣的同學可以自行查看相關的api和文檔。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25