python中的内置库--collections

python中的内置容器dict, list, tuple, set通常能处理日常大部分的问题,但对于一些特殊的应用场景,用这几种内置容器无法简洁高效的实现需求,所以python官方内置了collections模块——提供了一些替换Python的通用内置容器的备选容器。

OrderedDict有序字典

dict在Python3.6之前是无序的,而collections中的集合OrderedDict就相当于一个有序字典,插入顺序就是遍历的顺序。

而在Python3.6之后,默认的dict就已经是有序字典了,dict内部的数据结构保留了插入的顺序,并且效率比原来的dict更高。

但为了兼容性的原因,目前还是推荐使用OrderedDict

1
2
3
4
5
>>> from collections import OrderedDict
>>> OrderedDict([("a", 1), ("b", 2), ("c", 3)])
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> dict([("a", 1), ("b", 2), ("c", 3)])
{'a': 1, 'b': 2, 'c': 3}

defaultdict默认字典

defaultdict相比于dict就是每个键对应的值可以指定一个默认值。

在开发中经常会遇到这样一个场景:用所给的数据构建一个字典,要每个键对应一个列表,列表中存储相应的数据,像是user_dict = {"a": [0, 1], "b": [3]}这样;我们在构建这个字典的时候要考虑a是第一次插入还是第一次之后,因为第一次插入首先要user_dict["a"] = []然后再执行append操作,而第一次之后就只需要append就可以了。

在类似这种场景下使用defaultdict可以使两个逻辑一致。

1
2
3
4
5
6
7
8
9
10
11
from collections import defaultdict
data_01 = ["静态语言"]
data_02 = ["C", "C++", "Python", "JavaScript"] # 数据
data_03 = ("C", "C++", "Java") # 静态语言
result = defaultdict(list) # 默认值为[]的字典
for i in data_01:
for j in data_02:
if j in data_03:
result[i].append(j)
>>> result
defaultdict(list, {'静态语言': ['C', 'C++']})

namedtuple命名元组

我们都知道tuple是不可变的,而namedtuple也是如此,并且namedtuple之所以叫命名元组正是因为它还可以用属性名来访问值,当然也可以用索引(tuple的特性)。

namedtuple是一个函数,返回的是一个类,再通过namedtuple创建的类来创建对象。所以namedtuple可以快速的定义一些数据结构而不需要定义类来实现,同时因为tuple的不可变性,还可以用它来存储常量。

1
2
3
4
5
6
7
8
from collections import namedtuple
Circle = namedtuple("Circle", ['x', 'y', 'r']) # x, y坐标 r半径
circle = Circle(x=0, y=1, r=2)
>>> circle.x, circle.y
(0, 1)
>>> circle.r
2
# circle.r = 1 # AttributeError: can't set attribute

Counter计数器

Counter是一个简单计数器,计算可迭代序列中各元素的数量。

Counterdict的子类

1
2
3
4
from collections import Counter
c = Counter("aabbascc")
>>> c
Counter({'a': 3, 'b': 2, 's': 1, 'c': 2})

deque双端队列

deque相比list具有更高效的插入和删除操作,并且支持双向的插入删除,适用于队列和栈。

1
2
3
4
5
6
from collections import deque
q = deque(['a'])
q.append('x')
q.appendleft("y")
>>> q
deque(['y', 'a', 'x'])

ChainMap链式字典

ChainMap在平时我并没有使用过,通过官方文档和网上资料得知ChainMap用于创建多个字典连接在一起的单个视图,在视图上的操作会直接反映到连接起来的dict中。

换句话说:ChainMap用于连接多个字典,在ChainMap上查找就是在连起来的dict中进行查找,在ChainMap上进行写入删除就是在对应的dict中进行操作,我们可以把ChainMap看成一个大的字典。

1
2
3
4
5
import builtins
from collections import ChainMap
pylookup = ChainMap(locals(), globals(), vars(builtins)) # 模拟python的内部查找链
>>> pylookup
ChainMap({'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'from collections import defaultdict\ndata_01 = ["静态语言"]\ndata_02 = ["C", "C++", "Python", "JavaScript"] # 数据\ndata_03 = ("C", "C++", "Java") # 静态语言\nresult = defaultdict(list)......
觉得好的话就打赏Ta一瓶冰阔落吧