Python——詳解collections工具庫,一篇文章全搞定

2021-02-20 TechFlow
今天為大家介紹Python當中一個很好用也是很基礎的工具庫,叫做collections。collection在英文當中有容器的意思,所以顧名思義,這是一個容器的集合。這個庫當中的容器很多,有一些不是很常用,本篇文章選擇了其中最常用的幾個,一起介紹給大家。defaultdictdefaultdict可以說是這個庫當中使用最簡單的一個,並且它的定義也很簡單,我們從名稱基本上就能看得出來。它解決的是我們使用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)

namedtuplenamedtuple很特殊,它涉及到元編程的概念。簡單介紹一下元編程的概念,我們不做過多的深入。簡而言之,就是在常見的面向對象當中。我們都是定義類,然後通過類的構造函數來創建實例。而元編程指的是我們定義元類,根據元類創建出來的並不是一個實例,而是一個類。如果用模具和成品來分別比喻類和實例的話,元類相當於是模具的模具。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和文檔。今天的文章就是這些,如果覺得有所收穫,請順手點個在看或者轉發吧,你們的舉手之勞對我來說很重要。

相關焦點

  • python進階,詳解collections工具庫!
    作者:梁唐來源:早起Python大家好,今天為大家介紹python當中一個很好用也是很基礎的工具庫,叫做collections。collection在英文當中有容器的意思,所以顧名思義,這是一個容器的集合。這個庫當中的容器很多,有一些不是很常用,本篇文章選擇了其中最常用的幾個,一起介紹給大家。
  • 【Python基礎】Python之collections庫-Counter
    一、模塊概述1、模塊作用官方說法:collectio
  • 四種高性能數據類型,Python collections助你優化代碼、簡潔任務
    選自gitconnected作者:George Seif機器之心編譯參與:王子嘉、杜偉在這篇文章中,機器學習工程師 George Seif 介紹了 Python collections 模塊最受歡迎的四種數據類型以及它們各自的使用方法。這些數據類型可以對代碼進行優化,進而實現更簡潔的任務執行。
  • Python的collections原來這麼好用!
    為了讓大家更好的認識,本文詳細總結collections的相關知識,一起來學習吧!collections模塊:實現了特定目標的容器,以提供Python標準內建容器 dict、list、set、tuple 的替代選擇。Counter:字典的子類,提供了可哈希對象的計數功能。defaultdict:字典的子類,提供了一個工廠函數,為字典查詢提供了默認值。
  • 一文看懂Python collections模塊的高效數據類型
    這將Python的功能擴展到許多受歡迎的領域,包括機器學習、數據科學和Web開發等, 其中最好的模塊之一是Python的內置collections 模塊。一般來講,python的collections是用於存儲數據集合(比如列表list, 字典dict, 元組tuple和集合set)的容器。這些容器內置在Python中,可以直接使用。
  • 【萬字長文詳解】Python庫collections,讓你擊敗99%的Pythoner
    免責聲明:這篇文章是關於Python的一個相當高級的特性。如果你剛入門,建議先收藏,請等一等再學!通俗說法:Python內置的數據類型和方法,collections模塊在這些內置類型的基礎提供了額外的高性能數據類型,比如基礎的字典是不支持順序的,collections模塊的OrderedDict類構建的字典可以支持順序,collections模塊的這些擴展的類用處非常大,熟練掌握該模塊,可以大大簡化Python代碼,提高Python
  • 一篇文章入門Python生態系統
    譯者按:原文寫於2011年末,雖然文中關於Python 3的一些說法可以說已經不成立了,但是作為一篇面向從其他語言轉型到Python的程式設計師來說
  • 二十九、深入Python中的 collections 模塊
    「@Author:Runsen」collections模塊是一個不用不知道,一用就上癮的模塊。這裡主要介紹OrderedDict類、defaultdict類、Counter類、namedtuple類和deque類。
  • 推薦一些相見恨晚的 Python 庫 「二」
    上一篇文章 推薦一些相見恨晚的 Python 庫 「一」對 Awesome Python 做了個簡單的介紹,同時匯總了一部分優秀的
  • Python編程:開發工具(IDE)大匯總(附官方下載)
    最近有多位讀者留言,諮詢更便捷、高效的python編程開發工具(IDE),本文就給大家介紹四款業內常用的python軟體開發工具,並簡單介紹下每款軟體的特點,便於讀者按需選擇合適的學習軟體!Python安裝全過程詳解與驗證方法安裝pip安裝器,請參考往期文章:
  • python利用Counter模塊快速查找重複數據
    在上一篇中,我介紹了collections中的counter模塊,並簡單介紹了其使用。
  • Python標準庫 collections,你用過嗎?
    @Author: rusen 參看官方文檔計數器(counter)以字典的形式返回序列中各個字符出現的次數,值為key,次數為valueCounter是對字典類型的補充,用於追蹤值得出現次數 ps:具備字典的所有功能 + 自己的功能import collectionscounter_test = collections.Counter
  • 如何在Python 3中使用collections模塊
    collections模塊能夠幫助我們高效地填充和操作數據結構。在本教程中,我們將通過collections模塊中的三個類來幫助你處理元組、字典和列表。我們將使用namedtuples來創建帶有命名欄位的元組,使用defaultdict來在字典中精確地分組信息,以及使用deque來高效地向一個類列表對象的每一邊添加元素。
  • Python基礎篇-08 Python版本區別,Python 3和Python 2區別詳解
    公眾號關注「專攻python」,設為「星標」重磅文章,第一時間送達!!
  • 如何在python中引入高性能數據類型?
    作者|skura 來源|AI開發者 python 就像一件藝術珍藏品!python 最大的優點之一是它可以廣泛地選擇模塊和包。它們將 python 的功能擴展到許多流行的領域,包括機器學習、數據科學、web 開發、前端等等。其中最好的一個優點是 python 的內置 collections 模塊。
  • Python每天一分鐘:pass與assert語句詳解
    下面將為大家詳細介紹python中的pass和assert語句的功能與示例。python中的pass和assert語句pass語句詳解很多程式語言都提供了「空語句」支持,如C/C++/JAVAPython 也不例外,但由於Python的設計中剔除了分號作為終結代碼語句的支持, 所以python設計了單獨的關鍵字來支持空語句,即pass 語句.下面為大家演示pass語句的代碼:
  • python實踐乾貨分享:使用Counter進行計數統計,方法有哪些?
    python中計數統計,項目開發中我們經常用到,其實作用就是對某個事件發生的次數,進行統計。很多應用場景都會用到這個函數例如:抽查樣本中出現殘次品的次數;錯誤日誌中出現某個錯誤提示次數;一篇文章中出現多次重複的單詞或者語句;這類場景的有很多種實現方法。接下來給大家展示幾種不同實現方式。
  • Python函數詳解一(函數參數、變量作用域)
    Python函數函數是python程序的重要組成部分。所謂函數就是實現某一特定功能的代碼段,可重複使用,提高了代碼的利用率。
  • Python數據類型
    (10000000)]# memory: 2.0 GBnamedtuplefrom collections_cards) def__getitem__(self, position): """python內置方法, 實現切片的重載 即實現切片的協議 Arguments: position {tuple}} -- 切片信息 """ return
  • Python中break語句用法詳解!
    這篇文章主要介紹了詳解Python中break語句的用法,是Python入門的呼出知識,需要的朋友可以參考下 在Python中的break