在内置数据类型(dict、list、set、tuple)的基础上,collections 模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple 和 OrderedDict 等。
namedtuple
namedtuple 生成可以使用名字来访问元素内容的 tuple。
我们知道 tuple 可以表示不变集合,例如,一个点的二维坐标就可以表示成:
1 | 1, 2) p = ( |
但是,看到 (1, 2)
,很难看出这个 tuple 是用来表示一个坐标的。这时 namedtuple 就派上了用场:
1 | from collections import namedtuple |
类似的,如果要用坐标和半径表示一个圆,也可以用 namedtuple 定义:
1 | # namedtuple('名称', [属性list]): |
还可以表示扑克牌的花色和数值:
1 | from collections import namedtuple |
deque
双端队列,可以快速的从另外一侧追加和推出对象。使用 list 存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为 list 是线性存储,数据量大的时候,插入和删除效率很低。
deque 是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
1 | from collections import deque |
deque 除了实现 list 的 append()
和 pop()
外,还支持 appendleft()
和 popleft()
,这样就可以非常高效地往头部添加或删除元素。
OrderedDict
在 Python 3.6 之前使用 dict 时 Key 是无序的,在对 dict 做迭代时,我们无法确定 Key 的顺序。用 OrderedDict 可以保持字典中 Key 的顺序:
1 | from collections import OrderedDict |
另外,需要注意的是 OrderedDict 的 Key 会按照插入的顺序排列,不是 Key 本身排序:
1 | od = OrderedDict() |
注意: 从 Python 3.6 开始,字典的 Key 将会保留插入或声明时候的顺序,但并不是可以被排序的那种顺序。从 3.7 开始这成了正式的 Python 语言特性,3.6 改进的字典更节省内存,运行效率差不多,有一个 “副作用” 就是字典变成有序的了。
defaultdict
defaultdict 是带有默认值的字典。例如有如下值集合:
1 | values = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90] |
将所有大于 66 的值保存至字典的第一个 key 中,将小于 66 的值保存至第二个 key 的值中。即: {‘k1’: 大于66 , ‘k2’: 小于66}
原生字典的解决方法:
1 | values = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90] |
defaultdict 字典的解决方法:
1 | from collections import defaultdict |
使用 dict 时,如果引用的 Key 不存在,就会抛出 KeyError 。如果希望 key 不存在时,返回一个默认值,就可以用 defaultdict:
1 | from collections import defaultdict |
在 defaultdict 中默认值必须是 callable 的,如果想使用不可 callable 的值作为默认值,可以使用不带参数的匿名函数 lambda 解决,因为 lambda 是 callable 的:
1 | from collections import defaultdict |
Counter
Counter 类的目的是用来跟踪不可变条目中值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为 value。计数值可以是任意的 Interger(包括 0 和负数)。Counter 类和其他语言的 bags 或 multisets 很相似。
1 | 'abcdeabcdabcaba') c = Counter( |