Python算法黑科技collection模块
collection就是基于python基本数据类型并为之添加了一些新的功能,也可以说是提供了几种高级数据类型,在。
这个模块实现了特定目标的容器,以提供Python标准内建容器 dict
, list
, set
, 和 tuple
的替代选择。
功能 | 注释 |
---|---|
deque | 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop) |
ChainMap | 类似字典(dict)的容器类,将多个映射集合到一个视图里面 |
Counter | 字典的子类,提供了可哈希对象的计数功能 |
OrderedDict | 字典的子类,保存了他们被添加的顺序 |
defaultdict | 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值 |
namedtuple | 创建命名元组子类的工厂函数 |
deque
双端队列
deque
本质上就是实现了数据结构中队列的升级版,双端队列可以高效的实现插入和删除的双向列表,适用于队列和栈。
双端队列支持线程安全,在双端队列的任何一端执行添加和删除操作,它们的内存效率几乎相同(时间复杂度为O(1))。
from collections import deque
q= deque(['a','b','c'])
q.append('1')
q.appendleft('2')
print(q)
#deque(['2', 'a', 'b', 'c', '1'])
ChainMap
这个功能的目的是为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理。它通常比创建一个新字典和多次调用 update()
要快很多,因为我们这么做的话要新建一个数据结构,这样的话对空间和时间上的浪费都是不小得。
1、可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询,若该多个字典当中有相同的key时,只会显示第一个字典相对应的
value
2、当对
ChainMap
进行修改的时候总是只会对第一个字典进行修改3、
new_child()
方法实质上是在列表的第一个元素前放入一个字典,默认是{},而parents
是去掉了列表开头的元素
from collections import ChainMap
a = {"x":1, "z":3}
b = {"y":2, "z":4}
c = ChainMap(a,b)
print(c)
print("x: %d, y: %d, z: %d" % (c["x"], c["y"], c["z"]))
print("x: %d, y: %d, z: %d, z: %d " % (c["x"], c["y"], c["z"], c["z"]))
输出:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
x: 1, y: 2, z: 3, z: 3
Counter
计数器
Counter
是对字典类型的补充,用于追踪值出现的次数,它继承于字典,用于计数可哈希的对象,计数的数值可以是正整数、负整数和零。
from collections import Counter
c = Counter('asdadiuhiuchizuha')
print(c)
输出:Counter({'a': 3, 'i': 3, 'u': 3, 'h': 3, 'd': 2, 's': 1, 'c': 1, 'z': 1})
OrderedDict
有序字典
OrderedDict
和一般的dict
类似,但是还具有记忆字典中存储的key的插入顺序。但是现在OrderDict
可能用处不大了,因为从Python 3.7开始,一般的dict
也具有这个特性。
该功能按照需求使用,若最重要的是排序操作,而空间效率、迭代效率以及更新字典的性能是次要的,则使用该功能,否则用dict
即可
OrderedDict
可以处理频繁的需要重排的操作,适合于Track最近的操作;
判断两个OrderedDict
是否相等同时要求顺序也相同;
OrderedDict
的popitem(last=True)
中可以通过last参数控制pop哪一端的元素;
OrderedDict
的move_to_end(key, last=True)
可以高效的将元素移至末尾;
defaultdict
默认字典
关于defaultdict
,我们可以先看一下dict
中一个类似功能的函数setdefault(k, d=None)
:
d = {}
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
for k, v in s:
d.setdefault(k, []).append(v)
sorted(d.items())
[out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
在上述代码中,setdefault(k, d=[])
一句话相当于做了两件事情:一是获取key为k的的value,二是若该key不存在则设置其值为[]
。即,d.get(k, [])
以及如果key不存在就设置d[k] = []。现在再回到defaultdict
,defaultdict([default_factory[, ...]])
,构造方法中default_factory
默认是None
,defaultdict
是dict
的一个subclass,它重写了一个__missing__
方法以及拥有一个default_factory
属性。
-
__missing__(key)
-
该方法在当key不存在时才会且仅被
__getitem__()
调用,所以当使用dict.get()
方法获取一个不存在的键值时,返回结果为None
,而不是使用default_factory
; -
当
default_factory
为None
时,索引一个不存在的key
会引发KeyError
异常; -
当
default_factory
不为None
时,索引一个不存在的key
则使用default_factory
进行初始化并返回值from collections import defaultdict [in]:d2 = defaultdict(int ,a=1, b=2) [in]:d2['c'] [out]:0 [in]:d2 = defaultdict(int ,a=1, b=2) [in]:d2.get('c') [out]:None [in]:d2 [out]:defaultdict(int, {'a': 1, 'b': 2}) [in]:d1 = defaultdict(a=1, b=2) [in]:d1['c'] [out]:KeyError: 'c'
-
-
default_factory
该属性在上述
__missing__()
函数中使用,由构造函数中的default_factory
初始化,默认为None
因此,上述例子可以使用
defaultdict
来实现如下:s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] d = defaultdict(list) for k, v in s: d[k].append(v) sorted(d.items()) [out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
namedtuple
具名元组
见名知意,就是具有名字的元组,因为我们知道,元组是不可变类型,而且只能靠索引获得值,这里用具名元组目的就是让元组有名字方便查找
from collections import namedtuple
# namedtuple('名称', [属性list]):
point = namedtuple('p',['x','y'])
p = point(1,2)
print(p.x) #1
print(p.y) #2
这个可以用在函数返回多值的时候,因为是元组,这样写见名知意,为代码可读性提供了便利!