简单总结一下 collections 模块中各个数据类型的用法
Python 的内置数据数据类型包括 str, int, list, tuple, set, dict 等,有时这些数据类型满足不了我们的需求。标准库中的 collections 模块在这些内置数据类型的基础上,提供了几个额外的数据类型:
- namedtuple 命名元组,使用名字访问元素 New in version 2.6.
- deque 双端队列,可以快速的从头/尾两端添加或删除元素 New in version 2.4.
- Counter 计数器,用于对某项数据进行计数 New in version 2.7.
- OrderedDict 有序字典,保持插入顺序 New in version 2.7.
- defaultdict 带有默认值的字典 New in version 2.5.
- ChainMap 合并多个 map(dict),但保持原数据结构 New in version 3.3
- UserDict 将字典包装起来使得创建字典的子类更容易
- UserList 列表对象的包装器
- UserString 字符串对象的包装器
namedtuple¶
可以使用名称来访问元素的数据对象,返回一个 带 name fields 的子类
collections.namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)
field_names 用于指定数据对象的元素,可以是一个 str,例如 'x y' 或者 'x, y',也可以是一个包含字符串的序列类型,像 ['x', 'y']
常用方法
- _asdict() 将 namedtuple 转换为一个 OrderedDict
- _fields() 返回 name fields 中的 key
- _replace() 类似于 str 的 replace 方法
- _make() 通过一个序列或可迭代对象创建
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y', 'z'])
p = Point(10, 11, 12)
p
Point(x=10, y=11, z=12)
p.x
p.x + p.y + p.z
p2 = Point(11, y=22, z=33)
p2
d = p2._asdict() # 转换为字典
d
p2._replace(y=100) # 替换元素值
p._fields # 查看对象字段
Point._make(range(3)) # 通过一个序列或者可迭代对象创建一个对象
deque¶
deque 是 double-ended queue 的缩写,即双端队列。List 存储数据的优势在于按索引查找元素会很快,但是插入和删除元素就很慢了,因为 list 是基于数组实现的。deque 是为了高效实现插入和删除操作的双向列表,list存储数据的优势在于按索引查找元素会很快,但是插入和删除元素就很慢了,因为list是基于数组实现的。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈,而且线程安全。
collections.deque([iterable[, maxlen]])
deque 具有 list 的所有方法,此外还有 appendleft/popleft ,插入元素的复杂度 O(1), 而 list 是 O(n)
maxlen 用于指定 deque 的最大长度,当 deque 的长度达到最大时,先加入的元素会按加入顺序被移出 deque ,如果不指定 maxlen 则为无限长。
常用方法
- append
- extend
- appendleft
- appendright
- popleft
- popright
- rotate deque 内元素按顺序向后移动一位,最后一位移动到第一位
from collections import deque
dq = deque()
dq
dq.extend([1, 2, 3])
dq.extend([1, 2, 3])
dq
dq = deque(maxlen=2)
dq
dq.append(1)
dq.append(1)
dq
dq.append(3)
dq
dq.append(4)
dq
dq.appendleft(5)
dq
跑马灯程序
import sys
import time
from collections import deque
fancy_loading = deque('>--------------------')
cnt = 0
while cnt<20:
print('\r%s' % ''.join(fancy_loading),)
fancy_loading.rotate(1)
sys.stdout.flush()
time.sleep(0.05)
cnt += 1
Counter¶
Counter 用来统计相关元素的出现次数,返回一个 Counter 对象,类似于字典
collections.Counter([iterable-or-mapping])
常用方法
- update 追加元素
- most_common(n) 获取出现次数最多的 n 个元素
from collections import Counter
c = Counter('abracadabra')
c
c.update('zzzbbe') # 追加元素
c
c.most_common(3) # 获取出现频率最高的前 3 个字符
OrderedDict¶
OrderedDict 是 dict 的一个子类,支持所有 dict 的方法,保持 dict 的有序性
collections.OrderedDict([items])
常用方法
- popitem(last = True)
- move_to_end(key, last = True) 以上两个方法的 last 关键字参数都是控制从头还是尾弹出对象的
from collections import OrderedDict
d = OrderedDict({'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2})
d
d['cherry'] = 8
d
for k, v in d.items():
print(k, v)
d.keys()
d.pop('apple')
d
defaultdict¶
在普通的 dict 之上添加了 default_factory,使得 key 不存在时会自动生成相应类型的 value,default_factory 参数可以指定成 list, set, int 等各种合法类型
作用类似于 dict 中的 set_default 方法,代码更优雅一些
collections.defaultdict([default_factory[, …]])
from collections import defaultdict
d = defaultdict(lambda: None)
d
d['a']
print(d['b'])
d
d = defaultdict(int)
d["hello"]
d
from collections import ChainMap
dict1 = { 'a' : 1, 'b' : 2 }
dict2 = { 'b' : 3, 'c' : 4 }
chain = ChainMap(dict1, dict2)
chain
chain.maps
chain.keys()
list(chain.keys())
chain['b'] # 获取的是第一个字典中的值
chain['a']
chain['c']
chain['d'] = 5
chain['e'] = 6 # 被添加到了第一个字典中
chain
chain['b'] = 8 # 修改了第一个字典中的值
chain
m = chain.new_child() # 复制一个 ChainMap 对象
m['g'] = 10
m
chain
dict3 = { 'h' : 5 }
new_chain = chain.new_child(dict3) # 添加新字典
new_chain
有时用 ChainMap 替代 update 是个不错的选择,但是 ChainMap 的绝大多数方法都
只是在第一个字典上进行操作
UserDict UserList UserString¶
这三个类是分别对 dict、list、str 三种数据类型的包装,其主要是为方便用户实现自己的数据类型。在 Python2 之前,这三个类分别位于 UserDict、UserList、UserString 三个模块中,需要用类似于 from UserDict import UserDict 的方式导入。在 Python3 之后则被挪到了 collections 模块中。这三个类都是基类,如果用户要扩展这三种类型,只需继承这三个类即可。
References: