最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深度解析Python collections庫

 更新時間:2026年07月03日 08:51:49   作者:卷無止境  
本文主要介紹了深度解析Python collections庫,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Python 標準庫里藏著不少"寶藏",collections 就是其中最值得深挖的一個。它不是什么花哨的第三方包,而是隨 Python 一起安裝、隨時可用的內置模塊——卻偏偏被大量開發(fā)者長期忽視,習慣性地用普通 dict、list 硬撐所有場景。這篇文章就來系統(tǒng)梳理 collections 里的每一個數(shù)據(jù)類型,聊聊它們的設計邏輯、使用姿勢,以及真正適合它們發(fā)光發(fā)熱的場景。

一、namedtuple— 給元組起個名字,世界清晰多了

普通元組的問題人人都遇到過:point[0] 到底是 x 還是 y?三個月后回來看代碼,完全不知道自己在寫什么。namedtuple 就是為了解決這個痛點而生的。

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 5)
print(p.x, p.y)  # 3 5
print(p[0])      # 3,依然支持索引訪問

它本質上是元組的子類,不可變、內存緊湊,卻擁有字段名訪問的可讀性。和普通 class 相比,它不需要寫 __init__,也不需要 __repr__,天生就是"數(shù)據(jù)容器"的最佳形態(tài)。

核心特性

  • _asdict() 方法可以直接轉成 OrderedDict(Python 3.8+ 返回普通 dict)
  • _replace() 返回一個修改了某字段的新實例,原對象不變
  • _fields 屬性列出所有字段名
  • 支持設置 defaults 參數(shù),給字段加默認值
Employee = namedtuple('Employee', ['name', 'dept', 'salary'], defaults=[50000])
e = Employee('Alice', 'Engineering')
print(e.salary)  # 50000

適用場景

最典型的用途是替代輕量級數(shù)據(jù)類。比如解析 CSV 文件的每一行、表示數(shù)據(jù)庫查詢結果的一條記錄、封裝坐標/顏色/配置參數(shù)等。當你發(fā)現(xiàn)自己在寫 return (x, y, z) 然后調用方要靠注釋才能理解每個位置的含義時,就是換 namedtuple 的時候了。

Python 3.7 之后 dataclass 崛起,提供了可變性和更多功能,但 namedtuple不可變性和極低內存開銷在某些場景下依然是無可替代的優(yōu)勢。

二、deque— 雙端隊列,列表的高性能替代品

list 在尾部追加元素很快,但在頭部插入或刪除,時間復雜度是 O(n)O(n)O(n)——因為所有元素都要往后移。數(shù)據(jù)量一大,這個代價就很明顯了。deque(發(fā)音 "deck")用雙向鏈表結構解決了這個問題,兩端操作都是 O(1)O(1)O(1)。

from collections import deque

dq = deque([1, 2, 3])
dq.appendleft(0)   # 左端追加
dq.append(4)       # 右端追加
dq.popleft()       # 左端彈出
dq.pop()           # 右端彈出
print(dq)          # deque([1, 2, 3])

maxlen參數(shù):自動滾動的固定窗口

這是 deque 最迷人的特性之一。設置 maxlen 后,隊列滿了再追加新元素,舊元素會自動從另一端被擠出去,完全不需要手動管理。

recent = deque(maxlen=5)
for i in range(10):
    recent.append(i)
print(recent)  # deque([5, 6, 7, 8, 9], maxlen=5)

適用場景

  • 實現(xiàn)隊列(BFS)和棧:比用 list 模擬隊列性能好得多
  • 滑動窗口:日志系統(tǒng)保留最近 N 條記錄、實時數(shù)據(jù)流的移動平均
  • 撤銷/重做功能:用 maxlen 限制歷史記錄條數(shù)
  • 生產者-消費者模型:配合 rotate() 方法做循環(huán)緩沖區(qū)
# rotate 示例:向右旋轉
dq = deque([1, 2, 3, 4, 5])
dq.rotate(2)
print(dq)  # deque([4, 5, 1, 2, 3])

三、Counter— 計數(shù)這件事,它是專業(yè)的

統(tǒng)計詞頻、計算元素出現(xiàn)次數(shù)——這類需求幾乎每個項目都會遇到。手寫一個 for 循環(huán)加 if key in dict 當然能實現(xiàn),但 Counter 讓這件事優(yōu)雅得多。

from collections import Counter

words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
c = Counter(words)
print(c)  # Counter({'apple': 3, 'banana': 2, 'cherry': 1})

直接傳入任何可迭代對象,甚至字符串,立刻得到計數(shù)結果。

那些讓人驚喜的方法

most_common(n) 返回出現(xiàn)頻率最高的 n 個元素,底層用堆實現(xiàn),效率很高:

print(c.most_common(2))  # [('apple', 3), ('banana', 2)]

Counter 之間可以直接做算術運算,這個特性相當強大:

c1 = Counter({'a': 3, 'b': 2})
c2 = Counter({'a': 1, 'b': 4, 'c': 1})

print(c1 + c2)  # Counter({'b': 6, 'a': 4, 'c': 1})
print(c1 - c2)  # Counter({'a': 2})  # 負數(shù)結果被丟棄
print(c1 & c2)  # Counter({'a': 1, 'b': 2})  # 取最小值(交集)
print(c1 | c2)  # Counter({'b': 4, 'a': 3, 'c': 1})  # 取最大值(并集)

elements() 方法將計數(shù)展開成迭代器:

list(Counter({'a': 2, 'b': 3}).elements())
# ['a', 'a', 'b', 'b', 'b']

適用場景

  • NLP 文本分析:詞頻統(tǒng)計、詞云數(shù)據(jù)準備
  • 數(shù)據(jù)去重計數(shù):日志分析、用戶行為統(tǒng)計
  • 投票/排名系統(tǒng):快速找出最熱門的 N 項
  • 差異比較:兩個文本之間的詞匯差異
  • 字謎檢測:判斷兩個字符串是否是字母異位詞,Counter(s1) == Counter(s2) 一行搞定

四、defaultdict— 再也不用寫if key not in dict

寫過這樣的代碼嗎?

# 傳統(tǒng)寫法,繁瑣
result = {}
for word in words:
    if word not in result:
        result[word] = []
    result[word].append(something)

defaultdict 把這個模式徹底簡化了。它在訪問不存在的鍵時,自動調用你指定的工廠函數(shù)創(chuàng)建默認值,不會拋出 KeyError。

from collections import defaultdict

result = defaultdict(list)
for word in words:
    result[word].append(something)  # 直接用,不需要判斷

工廠函數(shù)可以是任何可調用對象:

dd_int   = defaultdict(int)    # 默認值 0
dd_list  = defaultdict(list)   # 默認值 []
dd_set   = defaultdict(set)    # 默認值 set()
dd_str   = defaultdict(str)    # 默認值 ''

# 也可以用 lambda 自定義
dd_custom = defaultdict(lambda: 'N/A')

構建嵌套結構

defaultdict 在構建多層嵌套字典時尤其好用:

# 構建圖的鄰接表
graph = defaultdict(list)
edges = [('A', 'B'), ('A', 'C'), ('B', 'D')]
for u, v in edges:
    graph[u].append(v)

# 二維分組統(tǒng)計
sales = defaultdict(lambda: defaultdict(int))
sales['Q1']['北京'] += 100
sales['Q1']['上海'] += 200

適用場景

  • 分組聚合:按某字段將數(shù)據(jù)分組,比 groupby 更靈活
  • 圖算法:構建鄰接表是最經典的用法
  • 詞頻統(tǒng)計的另一種寫法defaultdict(int) 配合 +=1
  • 緩存/記憶化:配合 lambda 做簡單的懶加載

五、OrderedDict— 有序字典的歷史使命與現(xiàn)代價值

Python 3.7 之后,普通 dict 已經按插入順序保存鍵了,這讓很多人覺得 OrderedDict 已經過時。但它依然有幾個獨特的能力,是普通 dict 給不了的。

from collections import OrderedDict

od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3

move_to_end()方法

這是 OrderedDict 獨有的殺手锏:

od.move_to_end('a')        # 把 'a' 移到末尾
od.move_to_end('c', last=False)  # 把 'c' 移到開頭

相等性比較的差異

普通 dict 的相等性只看鍵值對是否一致,不管順序;OrderedDict順序不同就不相等

d1 = {'a': 1, 'b': 2}
d2 = {'b': 2, 'a': 1}
print(d1 == d2)  # True

od1 = OrderedDict([('a', 1), ('b', 2)])
od2 = OrderedDict([('b', 2), ('a', 1)])
print(od1 == od2)  # False

適用場景

OrderedDict 最經典的應用是實現(xiàn) LRU 緩存(最近最少使用緩存)

class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict()
        self.capacity = capacity

    def get(self, key):
        if key not in self.cache:
            return -1
        self.cache.move_to_end(key)  # 訪問后移到末尾(最近使用)
        return self.cache[key]

    def put(self, key, value):
        if key in self.cache:
            self.cache.move_to_end(key)
        self.cache[key] = value
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)  # 淘汰最久未使用的

當然,Python 3.2 之后 functools.lru_cache 裝飾器已經內置了這個功能,但手動實現(xiàn) LRU 時 OrderedDict 依然是最優(yōu)雅的選擇。

六、ChainMap— 多個字典,一個視圖

ChainMap 把多個字典"鏈"在一起,形成一個邏輯上的單一映射。查找時按順序逐個字典搜索,找到第一個匹配就返回;寫入操作只作用于第一個字典。

from collections import ChainMap

defaults = {'color': 'red', 'user': 'guest', 'timeout': 30}
env_vars = {'user': 'admin', 'timeout': 60}
cli_args = {'color': 'blue'}

config = ChainMap(cli_args, env_vars, defaults)
print(config['color'])    # 'blue'(來自 cli_args)
print(config['user'])     # 'admin'(來自 env_vars)
print(config['timeout'])  # 60(來自 env_vars)

這個優(yōu)先級機制非常直觀:越靠前的字典優(yōu)先級越高。

與dict.update()的本質區(qū)別

{**defaults, **env_vars, **cli_args} 合并字典會創(chuàng)建一個全新的字典,原始數(shù)據(jù)的修改不會反映進來。ChainMap視圖,原始字典的變化會實時體現(xiàn):

config = ChainMap(cli_args, defaults)
defaults['timeout'] = 100
print(config['timeout'])  # 100,實時更新

適用場景

  • 配置系統(tǒng):命令行參數(shù) > 環(huán)境變量 > 配置文件 > 默認值,這種優(yōu)先級層疊是 ChainMap 的天然用途
  • 模板引擎的變量作用域:局部變量覆蓋全局變量
  • Python 解釋器內部locals()globals() 的關系就是類似的鏈式查找
  • A/B 測試配置:不同用戶群體使用不同配置層

七、UserDict、UserList、UserString— 繼承的正確姿勢

這三個類乍看之下有點奇怪——為什么要有 UserDict,直接繼承 dict 不行嗎?

答案是:直接繼承內置類型有坑dict 的某些方法(比如 __setitem__)在內部調用時不一定會走你重寫的版本,導致行為不一致。UserDict 是用純 Python 實現(xiàn)的字典包裝器,內部所有方法都會正確地調用彼此,繼承它來自定義字典行為更安全可靠

from collections import UserDict

class UpperDict(UserDict):
    """鍵自動轉大寫的字典"""
    def __setitem__(self, key, value):
        super().__setitem__(key.upper(), value)

ud = UpperDict()
ud['hello'] = 'world'
print(ud)        # {'HELLO': 'world'}
print(ud['HELLO'])  # 'world'

同理,UserList 適合自定義列表行為:

from collections import UserList

class BoundedList(UserList):
    """有最大長度限制的列表"""
    def __init__(self, max_size, *args):
        self.max_size = max_size
        super().__init__(*args)

    def append(self, item):
        if len(self.data) < self.max_size:
            super().append(item)
        else:
            raise ValueError(f"列表已滿,最多 {self.max_size} 個元素")

適用場景

  • 自定義數(shù)據(jù)驗證:插入時自動校驗類型或范圍
  • 只讀字典/列表:重寫寫入方法拋出異常
  • 帶日志的容器:每次修改自動記錄日志
  • 類型強制轉換:插入時自動轉換數(shù)據(jù)格式

八、全局視角:選哪個?

梳理完七個數(shù)據(jù)結構,用一張表來幫助快速定位:

數(shù)據(jù)類型核心特性最典型用途性能亮點
namedtuple不可變、有字段名的元組輕量數(shù)據(jù)類、函數(shù)多返回值內存占用與元組相同
deque雙端 O(1)O(1)O(1) 操作隊列、滑動窗口、BFS兩端操作遠優(yōu)于 list
Counter自動計數(shù) + 集合運算詞頻、排名、差異比較most_common 用堆優(yōu)化
defaultdict自動創(chuàng)建默認值分組聚合、圖鄰接表省去 KeyError 判斷
OrderedDict有序 + move_to_endLRU 緩存、順序敏感比較move_to_end 是 O(1)O(1)O(1)
ChainMap多字典鏈式查找視圖配置優(yōu)先級、作用域鏈無需復制數(shù)據(jù)
UserDict/List/String安全繼承內置類型自定義容器行為繼承語義完整可靠

寫在最后

collections 的設計哲學其實很簡單:為常見的編程模式提供專用工具。每一個數(shù)據(jù)結構背后都對應著一類反復出現(xiàn)的需求——計數(shù)、滑動窗口、分組、配置層疊……與其每次都從零開始用基礎類型拼湊,不如直接用這些經過充分測試、性能優(yōu)化的專用容器。

代碼的質量不只體現(xiàn)在邏輯正確,還體現(xiàn)在用對了工具??吹?Counter 的時候不再手寫計數(shù)循環(huán),看到 deque 的時候不再用 list.insert(0, x)——這種直覺,是 Python 開發(fā)者成長路上很重要的一步。

到此這篇關于深度解析Python collections庫的文章就介紹到這了,更多相關Python collections庫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解python 發(fā)送郵件實例代碼

    詳解python 發(fā)送郵件實例代碼

    本篇文章主要介紹了python 發(fā)送郵件實例代碼,詳細的介紹了各種方式發(fā)送郵件,包括文件形式的郵件、HTML形式的郵件、帶圖片的HTML郵件等,有興趣的可以了解一下。
    2016-12-12
  • Python Pandas處理csv文件常用示例

    Python Pandas處理csv文件常用示例

    Pandas是一個非常強大的數(shù)據(jù)操作python包,支持各種數(shù)據(jù)格式,包括CSV文件,本文就來介紹一下Python Pandas處理csv文件常用示例,感興趣的可以了解一下
    2023-12-12
  • python 去除二維數(shù)組/二維列表中的重復行方法

    python 去除二維數(shù)組/二維列表中的重復行方法

    今天小編就為大家分享一篇python 去除二維數(shù)組/二維列表中的重復行方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python操作kafka實踐的示例代碼

    python操作kafka實踐的示例代碼

    這篇文章主要介紹了python操作kafka實踐的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • Python3實時操作處理日志文件的實現(xiàn)

    Python3實時操作處理日志文件的實現(xiàn)

    本文主要介紹了Python3實時操作處理日志文件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Python網絡編程之socket與socketserver

    Python網絡編程之socket與socketserver

    這篇文章介紹了Python網絡編程之socket與socketserver,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Python基礎指南之轉義字符與原始字符串的妙用詳解

    Python基礎指南之轉義字符與原始字符串的妙用詳解

    本文詳細解析了Python轉義字符及其應用場景,涵蓋常用轉義字符、Unicode轉義及原始字符串,理解這些基礎知識能有效避免字符串處理中的常見錯誤
    2026-06-06
  • python 切換root 執(zhí)行命令的方法

    python 切換root 執(zhí)行命令的方法

    今天小編就為大家分享一篇python 切換root 執(zhí)行命令的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python日期和時間完全指南與實戰(zhàn)

    Python日期和時間完全指南與實戰(zhàn)

    在軟件開發(fā)領域,?日期時間處理?是貫穿系統(tǒng)設計全生命周期的重要基礎能力,本文將深入解析Python日期時間的?七大核心模塊?,通過?企業(yè)級代碼案例?揭示最佳實踐,感興趣的朋友一起看看吧
    2025-05-05
  • Django model 中設置聯(lián)合約束和聯(lián)合索引的方法

    Django model 中設置聯(lián)合約束和聯(lián)合索引的方法

    今天小編就為大家分享一篇Django model 中設置聯(lián)合約束和聯(lián)合索引的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08

最新評論

绥中县| 蒲城县| 托里县| 从江县| 锡林郭勒盟| 蓝田县| 襄垣县| 田阳县| 开化县| 富川| 南康市| 鄂尔多斯市| 孝感市| 汉源县| 榆树市| 安庆市| 鄂伦春自治旗| 金山区| 博客| 民权县| 齐齐哈尔市| 锦屏县| 封开县| 永胜县| 西华县| 且末县| 玉环县| 广宁县| 阿城市| 六枝特区| 潼关县| 章丘市| 镇沅| 平江县| 郑州市| 甘德县| 明光市| 东丰县| 涟源市| 海城市| 美姑县|