当前位置: 首页 > news >正文

Python 内置模块 collections 常用工具

今天我们来聊聊 Python 的 collections 模块,这个模块就像一个百宝箱,里面装了一堆超级实用的工具,能让你的代码更简洁、更高效。collections 提供了一些高级数据结构,比 Python 内置的列表、字典、集合等更强大,适合处理一些特定场景。

参考文章:Python 内置模块 collections | 简单一点学习 easyeasy.me

一、为什么要用 collections 模块?

Python 的内置数据类型(像 listdictset)已经很好用了,但有时候会遇到一些特殊需求,比如需要一个字典能记住插入顺序,或者需要一个计数器来统计元素出现的次数。这时候,collections 模块就派上用场了!它提供了一些专门的数据结构,帮你更高效地解决问题。

这篇文章我们会重点介绍以下几个 collections 模块的常用工具:

  1. namedtuple:给元组取名字,代码更清晰
  2. deque:双端队列,操作两端超快
  3. Counter:计数神器,统计元素频率
  4. OrderedDict:记住插入顺序的字典
  5. defaultdict:自带默认值的字典

二、namedtuple:给元组取个名字

元组 (tuple) 很好用,但它只能通过索引访问,比如 person[0]person[1],看着有点费劲。namedtuple 就像给元组的每个位置取了个名字,让你可以用 person.name 这样直观的方式访问。

用法

namedtuple 是一个工厂函数,用来创建带命名的元组类。基本语法是:

from collections import namedtuple
TypeName = namedtuple('TypeName', ['field1', 'field2', ...])

例子

假设我们要存一个人的信息,包括名字、年龄和城市:

from collections import namedtuple# 创建一个 Person 类
Person = namedtuple('Person', ['name', 'age', 'city'])# 创建一个 Person 实例
alice = Person(name='Alice', age=25, city='Beijing')# 访问属性
print(alice.name)  # 输出: Alice
print(alice.age)   # 输出: 25
print(alice.city)  # 输出: Beijing# 也可以像元组一样用索引
print(alice[0])    # 输出: Alice

优点

  • 代码可读性强,用 alice.namealice[0] 直观。
  • 比字典占用内存少,因为它是元组的子类,数据不可变。
  • 支持元组的所有操作,比如拆包、迭代等。

试试创建一个 Pointnamedtuple,表示 2D 坐标点,包含 xy,然后创建一个点 (3, 4),打印它的坐标。

Point = namedtuple('Point', ['x', 'y'])
p = Point(x=3, y=4)
print(f"Point: ({p.x}, {p.y})")  # 输出: Point: (3, 4)

三、deque:双端队列,左右都快

deque(读作 “deck”,双端队列)是一个高效的数据结构,适合在两端添加或删除元素。相比 listdeque 在首尾操作上速度更快,尤其适合队列和栈的场景。

用法

deque 的基本操作包括:

  • append / appendleft:在右端/左端添加元素
  • pop / popleft:在右端/左端删除并返回元素
  • extend / extendleft:在右端/左端添加多个元素

例子

我们来模拟一个任务队列:

from collections import deque# 创建一个双端队列
tasks = deque(['task1', 'task2', 'task3'])# 右端添加任务
tasks.append('task4')
print(tasks)  # 输出: deque(['task1', 'task2', 'task3', 'task4'])# 左端添加优先任务
tasks.appendleft('urgent_task')
print(tasks)  # 输出: deque(['urgent_task', 'task1', 'task2', 'task3', 'task4'])# 处理任务(从左端取)
current_task = tasks.popleft()
print(f"处理任务: {current_task}")  # 输出: 处理任务: urgent_task
print(tasks)  # 输出: deque(['task1', 'task2', 'task3', 'task4'])

优点

  • 首尾操作的时间复杂度是 O(1),而 list 的头部操作是 O(n)。
  • 适合实现队列、栈,或者需要频繁在两端操作的场景。

deque 实现一个简单的栈(后进先出):

stack = deque()
stack.append('a')
stack.append('b')
print(stack.pop())  # 输出: b
print(stack.pop())  # 输出: a

四、Counter:计数神器

Counter 是一个专门用来计数的工具,特别适合统计列表、字符串等可迭代对象中元素的出现次数。它返回一个字典-like 的对象,键是元素,值是出现的次数。

用法

直接把可迭代对象丢给 Counter,它会帮你统计好。

例子

统计一句话中每个单词出现的次数:

from collections import Countersentence = "apple banana apple orange banana apple"
words = sentence.split()
word_counts = Counter(words)print(word_counts)  # 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
print(word_counts['apple'])  # 输出: 3# 获取出现次数最多的两个单词
print(word_counts.most_common(2))  # 输出: [('apple', 3), ('banana', 2)]

更多用法

  • 合并计数:可以用 +- 合并两个 Counter
  • 获取所有元素:elements() 方法返回一个迭代器,按计数展开元素。
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2)  # 输出: Counter({'a': 4, 'b': 3})
print(list(c1.elements()))  # 输出: ['a', 'a', 'a', 'b']

统计一个字符串中每个字符的出现次数:

text = "hello"
char_counts = Counter(text)
print(char_counts)  # 输出: Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

五、OrderedDict:记住插入顺序的字典

在 Python 3.7 之前,普通字典不保证键的插入顺序。OrderedDict 是一个特殊的字典,能记住键值对的插入顺序。虽然 Python 3.7+ 的普通字典已经支持顺序,但 OrderedDict 还有一些独特的功能,比如移动元素。

用法

跟普通字典差不多,但它会记住插入顺序。

例子

记录学生的加入顺序:

from collections import OrderedDictstudents = OrderedDict()
students['Alice'] = 95
students['Bob'] = 88
students['Charlie'] = 92print(students)  # 输出: OrderedDict([('Alice', 95), ('Bob', 88), ('Charlie', 92)])# 移动某个键到末尾
students.move_to_end('Bob')
print(students)  # 输出: OrderedDict([('Alice', 95), ('Charlie', 92), ('Bob', 88)])

优点

  • 明确保证插入顺序,适合需要顺序的场景。
  • move_to_endpopitem(last=False) 等方法,灵活操作顺序。

创建一个 OrderedDict,按顺序添加三个键值对,然后把第一个键移动到末尾:

od = OrderedDict(a=1, b=2, c=3)
od.move_to_end('a')
print(od)  # 输出: OrderedDict([('b', 2), ('c', 3), ('a', 1)])

六、defaultdict:自带默认值的字典

普通字典在访问不存在的键时会报 KeyError,而 defaultdict 会在访问不存在的键时自动创建一个默认值,省去手动初始化的麻烦。

用法

创建 defaultdict 时需要指定一个默认工厂函数,比如 intlistset 等。

例子

统计每个字母开头的单词:

from collections import defaultdictwords = ['apple', 'banana', 'ant', 'bear', 'cat']
d = defaultdict(list)  # 默认值是空列表for word in words:d[word[0]].append(word)print(d)  # 输出: defaultdict(<class 'list'>, {'a': ['apple', 'ant'], 'b': ['banana', 'bear'], 'c': ['cat']})

更多例子

int 作为默认值来计数:

counts = defaultdict(int)
for char in "hello":counts[char] += 1print(counts)  # 输出: defaultdict(<class 'int'>, {'h': 1, 'e': 1, 'l': 2, 'o': 1})

优点

  • 避免 KeyError,简化代码。
  • 适合需要动态初始化的场景,比如分组、计数。

defaultdict 统计一个列表中每个数字的出现次数:

numbers = [1, 2, 2, 3, 1, 4]
counts = defaultdict(int)
for num in numbers:counts[num] += 1
print(counts)  # 输出: defaultdict(<class 'int'>, {1: 2, 2: 2, 3: 1, 4: 1})

七、总结和实践建议

collections 模块的这些工具各有妙用,总结一下:

  • namedtuple:适合定义轻量级、不可变的数据结构。
  • deque:适合需要高效首尾操作的场景,比如队列和栈。
  • Counter:统计元素频率的神器。
  • OrderedDict:需要记住插入顺序时用(Python 3.7+ 可选)。
  • defaultdict:避免 KeyError,简化动态初始化。
http://www.dtcms.com/a/336640.html

相关文章:

  • 【撸靶笔记】第二关:GET -Error based -Intiger based
  • Spring Framework :IoC 容器的原理与实践
  • CW32L011_电机驱动器开发板试用
  • 工作中使用到的时序指标异常检测算法 TRPS 【Temporal Residual Pattern Similarity】和 K-sigma 算法
  • 区块链:数字时代信任基石的构建与创新
  • 25年第十本【金钱心理学】
  • 1. Docker的介绍和安装
  • 洛谷 P2324 [SCOI2005] 骑士精神-提高+/省选-
  • CE桥接MuMu模拟器
  • 计算机网络 Session 劫持 原理和防御措施
  • IC验证 AHB-RAM 项目(一)——项目理解
  • 【leetcode】58. 最后一个单词的长度
  • Python大模型应用开发-核心技术与项目开发
  • 【165页PPT】基于IPD的研发项目管理(附下载方式)
  • vue路由懒加载
  • 数据链路层(1)
  • Linux操作系统软件编程——多线程
  • 基于飞算JavaAI实现高端算法性能优化:从理论到落地的性能跃迁实践
  • C++---迭代器删除元素避免索引混乱
  • 【Golang】:函数和包
  • 因果语义知识图谱如何革新文本预处理
  • os详解,从上面是‘os‘模块?到核心组成和常用函数
  • 智能合约里的 “拒绝服务“ 攻击:让你的合约变成 “死机的手机“
  • 什么是AI Agent(智能体)
  • nature子刊:MCNN基于电池故障诊断的模型约束的深度学习方法
  • [Oracle数据库] Oracle 多表查询
  • 网络常识-我的电脑啥时安装了证书
  • 生成模型实战 | InfoGAN详解与实现
  • java如何使用正则提取字符串中的内容
  • 谈谈对面向对象OOP的理解