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

深度解析Python collections庫

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

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

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

核心特性

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

適用場景

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

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

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

list 在尾部追加元素很快,但在頭部插入或刪除,時間復(fù)雜度是 O(n)O(n)O(n)——因為所有元素都要往后移。數(shù)據(jù)量一大,這個代價就很明顯了。deque(發(fā)音 "deck")用雙向鏈表結(jié)構(gòu)解決了這個問題,兩端操作都是 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 最迷人的特性之一。設(shè)置 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ù)
  • 生產(chǎn)者-消費者模型:配合 rotate() 方法做循環(huán)緩沖區(qū)
# rotate 示例:向右旋轉(zhuǎn)
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 當(dāng)然能實現(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ù)結(jié)果。

那些讓人驚喜的方法

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

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

Counter 之間可以直接做算術(shù)運算,這個特性相當(dāng)強大:

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ù)結(jié)果被丟棄
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 把這個模式徹底簡化了。它在訪問不存在的鍵時,自動調(diào)用你指定的工廠函數(shù)創(chuàng)建默認值,不會拋出 KeyError。

from collections import defaultdict

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

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

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')

構(gòu)建嵌套結(jié)構(gòu)

defaultdict 在構(gòu)建多層嵌套字典時尤其好用:

# 構(gòu)建圖的鄰接表
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 更靈活
  • 圖算法:構(gòu)建鄰接表是最經(jīng)典的用法
  • 詞頻統(tǒng)計的另一種寫法defaultdict(int) 配合 +=1
  • 緩存/記憶化:配合 lambda 做簡單的懶加載

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

Python 3.7 之后,普通 dict 已經(jīng)按插入順序保存鍵了,這讓很多人覺得 OrderedDict 已經(jīng)過時。但它依然有幾個獨特的能力,是普通 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 最經(jīng)典的應(yīng)用是實現(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)  # 淘汰最久未使用的

當(dāng)然,Python 3.2 之后 functools.lru_cache 裝飾器已經(jīng)內(nèi)置了這個功能,但手動實現(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()的本質(zhì)區(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 解釋器內(nèi)部locals()globals() 的關(guān)系就是類似的鏈式查找
  • A/B 測試配置:不同用戶群體使用不同配置層

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

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

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

from collections import UserDict

class UpperDict(UserDict):
    """鍵自動轉(zhuǎn)大寫的字典"""
    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ù)驗證:插入時自動校驗類型或范圍
  • 只讀字典/列表:重寫寫入方法拋出異常
  • 帶日志的容器:每次修改自動記錄日志
  • 類型強制轉(zhuǎn)換:插入時自動轉(zhuǎn)換數(shù)據(jù)格式

八、全局視角:選哪個?

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

數(shù)據(jù)類型核心特性最典型用途性能亮點
namedtuple不可變、有字段名的元組輕量數(shù)據(jù)類、函數(shù)多返回值內(nèi)存占用與元組相同
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)先級、作用域鏈無需復(fù)制數(shù)據(jù)
UserDict/List/String安全繼承內(nèi)置類型自定義容器行為繼承語義完整可靠

寫在最后

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

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

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

相關(guān)文章

  • 詳解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ù)組/二維列表中的重復(fù)行方法

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

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

    python操作kafka實踐的示例代碼

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

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

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

    Python網(wǎng)絡(luò)編程之socket與socketserver

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

    Python基礎(chǔ)指南之轉(zhuǎn)義字符與原始字符串的妙用詳解

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

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

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

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

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

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

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

最新評論

海淀区| 腾冲县| 商洛市| 南汇区| 嘉义县| 沙雅县| 孟州市| 静安区| 黄龙县| 长兴县| 宁蒗| 满洲里市| 邢台市| 灌南县| 连城县| 文山县| 卢龙县| 大名县| 集贤县| 葫芦岛市| 读书| 清苑县| 武安市| 堆龙德庆县| 富顺县| 遂平县| 开原市| 台东市| 宣恩县| 荥经县| 封丘县| 甘泉县| 芜湖县| 邵东县| 桐梓县| 金坛市| 田阳县| 汪清县| 株洲市| 清远市| 东兰县|