前言:
collections
是实现了特定目标的容器,以提供python标准内建容器dict
,list
,set
和tuple
的替代选择。
Counter
Counter是一个dict
子类,主要是用来对你访问的对象的频率进行计数
import collections
#统计字符出现的次数
test1 = collections.Counter('hello world')
#统计单词出现的次数
test2 = collections.Counter('hello world'.split())
print(test1)
'''Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})'''
print(test2)
'''Counter({'hello': 1, 'world': 1})'''
常用方法:
- elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略
- most_commen([n]):返回一个列表,提供n个访问频率最高的元素和计数
- subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者是负数
- update([iterable-or-mapping]):从迭代对象计数元素或者从另一个映射对象/计数器添加
import collections
a = collections.Counter('hello world'.split())
print(a)
#获取指定对象的访问次数,也可以用get获取
print(a.get('hello'))
print(a['hello'])
#查看元素
print(list(a.elements()))
b = collections.Counter('你好 世界'.split())
#追加对象,也可以使用a.update(b)
print(a+b)
#减少对象,也可以使用a.subtract(b)
print(a-b)
#清除
print(a.clear())
defaultdict
返回一个新的类似字典的对象,defaultdict
是内置dict
类的子类
defaultdict
一个经典用法是使用其中一种内置类型(dict
,int
,list
或str
等)作为默认工厂,这些内置类型在没有参数调用时返回空类型
import collections
#使用str
a = collections.defaultdict(str)
print(a)
'''defaultdict(, {})'''
print(a['hello'])
''' '''
print(a)
'''defaultdict(, {'hello': ''})'''
#使用int
fruit = collections.defaultdict(int)
fruit['apple'] = 2
print(fruit)
'''defaultdict(, {'apple': 2})'''
#没有对象时返回0
print(fruit['banana'])
'''0'''
#使用list
b = [('yellow',1),('red',2),('green',3)]
c = collections.defaultdict(list)
for k,v in b:
c[k].append(v)
print(c)
'''defaultdict(, {'yellow': [1], 'red': [2], 'green': [3]})'''
print(c.items())
'''dict_items([('yellow', [1]), ('red', [2]), ('green', [3])])'''
#使用dict
d = collections.defaultdict(dict)
d[1] = {'one',1}
print(d)
'''defaultdict(, {1: {1, 'one'}})'''
#使用set
phone = collections.defaultdict(set)
phone['品牌'].add('小米')
phone['品牌'].add('苹果')
phone['处理器'].add('联发科')
print(phone)
'''defaultdict(, {'品牌': {'苹果', '小米'}, '处理器': {'联发科'}})'''
OrderdDict
- Python字典中的键的顺序是任意的,它们不收添加的顺序的控制
-
colletions.OrderdDict
类提供了保留他们添加顺序的字典对象
import collections
ot = collections.OrderedDict()
ot['k1'] = ''
ot['k3'] = ''
ot['k2'] = ''
print(ot)
'''OrderedDict([('k1', ''), ('k3', ''), ('k2', '')])'''
#如果在已经存在的key上添加新的值,将会保留原来的key的值,然后覆盖value值
ot['k1'] = 666
print(ot)
'''OrderedDict([('k1', 666), ('k3', ''), ('k2', '')])'''
print(dict(ot))
'''{'k1': 666, 'k3': '', 'k2': ''}'''
namedtuple
三种定义命名元组的方法,第一个参数是命名元组的构造器(如下所示:Person1,Person2,Person3)
import collections
p1 = collections.namedtuple('Person1',['name','sex','age'])
p2 = collections.namedtuple('Person2','name,sex,age')
p3 = collections.namedtuple('Person3','name sex age')
#实例化命名元组
zhangsan = p1('张三','男',28)
print(zhangsan)
'''Person1(name='张三', sex='男', age=28)'''
lisi = p2('李四','女',24)
print(lisi)
'''Person2(name='李四', sex='女', age=24)'''
print(lisi.name)
'''李四'''
deque
collections.deque返回一个双向队列对象,从左到右初始化(append()
),从iterable(迭代对象)数据创建。如果iterable没有指定,新队列为空;
collections.deque队列支持线程安全,对于从两端添加append()
或者弹出pop
,复杂度都是O(1);
如果长度没有指定或者是None,deque可以增长到任意长度。否则,deque就限定到指定最大长度。一旦限定长度的deque满了,当新项加入时,同样数量的项就从另一端弹出;
支持的方法:
- append(x):添加x到右端
- appendleft(x):添加x到左端
- clear():清除所有元素,长度变为0
- copy():创建一份浅拷贝
- count(x):计算队列中个数等于x的元素
- extend(iterable):在队列右侧添加iterable中的元素
- extendleft(iterable):在队列左侧添加iterable中的元素【iterable参数的顺序会反过来添加】
- index(x[,start[,stop]]):返回第x个元素【从start开始计算,stop之前】。返回第一个匹配,如果没找到,跑出ValueError异常错误
- insert(i,x):在 i 位置插入x,【如果插入会导致一个限定deque超出最大长度的话,就抛出InderErrory异常错误】
- pop():移除最右侧的元素
- popleft():移除最左侧的元素
- remove(value):移去找到的第一个value,没有抛出ValueError异常错误
- reverse():将deque逆序排列。返回None
- maxlen():队列的最大长度,没有限定则为None
import collections
x = collections.deque(maxlen=10)
print(x)
'''deque([], maxlen=10)'''
x.extend('Python')
print(x)
'''deque(['P', 'y', 't', 'h', 'o', 'n'], maxlen=10)'''
x.append('a')
x.appendleft('H')
x.appendleft('P')
x.appendleft('P')
print(x)
'''deque(['P', 'P', 'H', 'P', 'y', 't', 'h', 'o', 'n', 'a'], maxlen=10)'''
x.appendleft('P')
print(x)
'''deque(['P', 'P', 'P', 'H', 'P', 'y', 't', 'h', 'o', 'n'], maxlen=10)'''
ChainMap
我们有多个字典或者映射,想把他们合并成为一个单独的映射,有人说是可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap。可以用来合并两个或者多个字典。当查询的时候,从前往后依次查询,简单使用。
import collections
test1 = {'apple':1,'banana':2}
test2 = {'orange':2,'apple':3,'pike':1}
comb1 = collections.ChainMap(test1,test2)
comb2 = collections.ChainMap(test2,test1)
print(comb1)
'''ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1})'''
print(comb2)
'''ChainMap({'orange': 2, 'apple': 3, 'pike': 1}, {'apple': 1, 'banana': 2})'''
for k,v in comb1.items():
print(k,v)
'''
orange 2
apple 1
pike 1
banana 2
'''
#当ChainMap进行修改的时候总是只会对第一个字典进行修改,如果第一个字典不存在该键,会添加
print(comb1['apple'])
'''1'''
comb1['apple'] = 2
print(comb1)
'''ChainMap({'apple': 2, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1})'''
print(comb1['pike'])
'''1'''
comb1['pike'] = 3
print(comb1)
'''ChainMap({'apple': 2, 'banana': 2, 'pike': 3}, {'orange': 2, 'apple': 3, 'pike': 1})'''
从原理上讲,ChainMap实际上是把放入的字典存储在一个队列里,当进行字典的增删等操作只会在第一个字典中进行。当进行查询的时候会依次查找,new_child()
方法实质上是在列表的第一个元素前放入一个字典,默认是{},而parents
是去掉列表开头的元素
import collections
a = collections.ChainMap()
a['x'] = 1
print(a)
'''ChainMap({'x': 1})'''
b = a.new_child()
print(b)
'''ChainMap({}, {'x': 1})'''
b['x'] = 2
print(b)
'''ChainMap({'x': 2}, {'x': 1})'''
c = a.new_child()
c['y'] = 2
print(c)
'''ChainMap({'y': 2}, {'x': 1})'''
d = c.parents
print(d)
'''ChainMap({'x': 1})'''