python的collections库
前言
用了这么长时间的python,一直觉得collections库里面的东西真是太好用了,然而发现很多人竟然还没听过,忍不住想安利一下。
简介
collections是python标准库中的一员。官方文档解释为:Container datatypes。提供了对python的基础(容器)数据类型dict、list、set、tuple的替代选择。
模块内成员有:
- namedtuple # 命名元组
- deque # 双端队列
- ChainMap # 链式字典
- Counter # 计数器
- OrderedDict # 有序字典
- defaultdict # 默认值字典
- UserDict
- UserList
- UserString
namedtuple(命名元组)
1 | collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None) |
导入
1 | from collections import namedtuple |
创建
1 | Point = namedtuple('Point', ['x', 'y']) |
用法
1 | # 类tuple操作 |
用途
因为namedtuple更节省内存
- 代替某些仅需要访问数据的类
1
2
3
4
5
6
7
8class Stock(object):
def __init__(self,name,shares,price):
self.name = name
self.shares = shares
self.price = price
# or
import collections
Stock = collections.namedtuple('Stock','name shares price') - 代替不需要改变的字典
原理
1.为啥会节省内存?
TODO
2.如何实现的属性访问?
查看源码,发现其实就是给每个参数做了个别名,实质还是通过索引去访问数据
1 | print(p._source) |
deque(双端队列)
1 | class collections.deque([iterable[, maxlen]]) |
Deque队列是由栈或者queue队列生成的(发音是 “deck”,”double-ended queue”的简称)。Deque 支持线程安全,内存高效添加(append)和弹出(pop),从两端都可以,两个方向的大概开销都是 O(1) 复杂度。
虽然 list 对象也支持类似操作,不过这里优化了定长操作和 pop(0) 和 insert(0, v) 的开销。它们引起 O(n) 内存移动的操作,改变底层数据表达的大小和位置。
如果 maxlen 没有指定或者是 None ,deques 可以增长到任意长度。否则,deque就限定到指定最大长度。一旦限定长度的deque满了,当新项加入时,同样数量的项就从另一端弹出。限定长度deque提供类似Unix filter tail 的功能。它们同样可以用与追踪最近的交换和其他数据池活动。
创建
1 | test_deque = collections.deque([1, 2, 3, 4], 1000) |
用法
1 | from collections import deque |
用途
- deque特点在于双端操作速度都快,如果要将数据插入列表头部或者从头部提取数据(保持处理顺序)则使用deque能够提升很大效率
- deque支持限制队列长度,在某些类型的应用,比如保留1000条日志时很有用。
性能测试结果
1 | # coding:utf8 |
ChainMap
一个 ChainMap 将多个字典或者其他映射组合在一起,创建一个单独的可更新的视图。 如果没有 maps 被指定,就提供一个默认的空字典,这样一个新链至少有一个映射。
创建
1 | from collections import ChainMap |
用途
- 模拟python内部lookup链
1
2import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))
Counter
一个计数器工具提供快速和方便的计数
创建
1 | from collections import Counter |
用法
- 计数
1
2
3
4
5
6c = Counter(["a", "a", "b", "c", "d"])
# >>> Counter({'a': 2, 'b': 1, 'c': 1, 'd': 1})
c += Counter(["a", "a", "b", "c", "d"])
# >>> Counter({'a': 4, 'b': 2, 'c': 2, 'd': 2})
c -= Counter(["a", "a", "b", "c", "d"])
# >>> Counter({'a': 2, 'b': 1, 'c': 1, 'd': 1}) - 统计重复最多的元素
1
2
3c = Counter(["a", "a", "b", "c", "d"])
c.most_common(1)
# >>> [('a', 4)]
defaultdict
1 | class collections.defaultdict([default_factory[, ...]]) |
返回一个新的类似字典的对象。 defaultdict 是内置 dict 类的子类。它重载了一个方法并添加了一个可写的实例变量
创建
1 | from collections import defaultdict |
用法
提供默认值
1
2
3
4
5
6
7d = defaultdict(int)
print(d["xxx"])
# >>> 0
d = {}
print(d.get("xxx", 0))
# >>> 0对多层嵌套数据结构提供默认值
1
2
3
4# 预定义数据结构
d = defaultdict(lambda: {"name": "", "child": defaultdict(str)})
print(d["xxx"]["child"]["tom"])省去if判断
1
2
3
4
5
6
7
8
9
10
11d = defaultdict(list)
d["name"].append("xxx")
d["age"].append("111")
print(d)
# >>> defaultdict(<class 'list'>, {'name': ['xxx'], 'age': ['111']})
d = {}
if "name" not in d:
d["name"] = []
d["name"].append("xxx")