飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

collections模块

collections 模块提供了 Python 通用内置容器(dict、list、set、tuple)的替代选择,以及专门化的容器数据类型。这些类型在特定场景下比普通内置类型更高效或更方便。

Counter:计数器

Counter 是字典的子类,用于计数可哈希对象:

from collections import Counter

# 统计字符频率
text = "hello world"
counts = Counter(text)
print counts              # Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
print counts['l']         # 3
print counts.most_common(3)   # [('l', 3), ('o', 2), ('h', 1)] —— 最常见的 3 个

# 统计单词
words = "the quick brown fox jumps over the lazy dog".split()
word_counts = Counter(words)
print word_counts['the']      # 2

Counter 的运算:

c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)

print c1 + c2             # Counter({'a': 4, 'b': 3}) —— 相加
print c1 - c2             # Counter({'a': 2}) —— 相减(只保留正数)
print c1 & c2             # Counter({'a': 1, 'b': 1}) —— 取最小
print c1 | c2             # Counter({'a': 3, 'b': 2}) —— 取最大

defaultdict:默认字典

defaultdict 在访问不存在的键时自动创建默认值,避免 KeyError:

from collections import defaultdict

# 普通字典需要手动处理
groups = {}
for key, value in [('a', 1), ('b', 2), ('a', 3)]:
    if key not in groups:
        groups[key] = []
    groups[key].append(value)

# defaultdict 自动创建列表
groups = defaultdict(list)
for key, value in [('a', 1), ('b', 2), ('a', 3)]:
    groups[key].append(value)

print dict(groups)        # {'a': [1, 3], 'b': [2]}

常用默认值工厂:

from collections import defaultdict

# 默认整数(计数)
counts = defaultdict(int)
counts['a'] += 1
print counts['a']         # 1
print counts['b']         # 0(自动创建)

# 默认集合
tags = defaultdict(set)
tags['python'].add('programming')
tags['python'].add('language')
print dict(tags)          # {'python': set(['language', 'programming'])}

# 默认字典
nested = defaultdict(dict)
nested['user']['name'] = 'Alice'
print dict(nested)        # {'user': {'name': 'Alice'}}

OrderedDict:有序字典

OrderedDict 保持键的插入顺序:

from collections import OrderedDict

od = OrderedDict()
od['first'] = 1
od['second'] = 2
od['third'] = 3

for key, value in od.items():
    print key, value
# first 1
# second 2
# third 3

普通 dict 在 Python 2.7 中不保证顺序(虽然实现上通常有序,但不应依赖)。

实际应用:LRU 缓存

from collections import OrderedDict

class LRUCache(object):
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()
    
    def get(self, key):
        if key not in self.cache:
            return -1
        # 移动到末尾(最近使用)
        value = self.cache.pop(key)
        self.cache[key] = value
        return value
    
    def put(self, key, value):
        if key in self.cache:
            self.cache.pop(key)
        elif len(self.cache) >= self.capacity:
            # 移除最旧的
            self.cache.popitem(last=False)
        self.cache[key] = value

namedtuple:命名元组

namedtuple 创建带有命名字段的元组子类,让元组像对象一样访问:

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)

print p.x             # 11
print p.y             # 22
print p[0]            # 11 —— 仍然是元组,支持索引
print p               # Point(x=11, y=22)

与普通类的对比:

# namedtuple:不可变,内存小,性能好
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)

# 普通类:可变,功能多
class PointClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

pc = PointClass(1, 2)

namedtuple 适合存储纯数据(Data Transfer Object),不可变且内存占用小。

实际应用:

from collections import namedtuple

# 定义数据结构
Employee = namedtuple('Employee', ['name', 'id', 'department'])

employees = [
    Employee('Alice', 'E001', 'Engineering'),
    Employee('Bob', 'E002', 'Sales'),
]

for emp in employees:
    print "%s (%s) works in %s" % (emp.name, emp.id, emp.department)

deque:双端队列

deque(double-ended queue)支持两端高效添加和移除元素:

from collections import deque

d = deque([1, 2, 3])
d.append(4)               # 右端添加
d.appendleft(0)         # 左端添加
print list(d)           # [0, 1, 2, 3, 4]

print d.pop()           # 4 —— 右端移除
print d.popleft()       # 0 —— 左端移除

与列表的性能对比:

操作listdeque
appendO(1)O(1)
appendleftO(n)O(1)
popO(1)O(1)
popleftO(n)O(1)

列表在头部插入/删除需要移动所有元素,是 O(n)。deque 两端都是 O(1)。

实际应用:滑动窗口

from collections import deque

def moving_average(iterable, n=3):
    it = iter(iterable)
    d = deque(maxlen=n)
    
    for x in it:
        d.append(x)
        if len(d) == n:
            yield sum(d) / float(n)

for avg in moving_average([40, 30, 50, 46, 39, 44]):
    print avg
# 40.0, 42.0, 45.0, 43.0

maxlen 限制队列大小,超出时自动从另一端移除。

选择指南

需求推荐类型
计数Counter
自动创建默认值defaultdict
保持插入顺序OrderedDict
纯数据对象namedtuple
两端频繁操作deque
一般键值存储普通 dict
上一页
json模块
下一页
math与random模块