Python的collections模块真的很好用
collections是实现了特定目标的容器,以提供Python标准内建容器dict,list,set,和tuple的替代选择。为了让大家更好的认识,本文详细总结collections的相关知识,一起来学习吧!
collections模块:实现了特定目标的容器,以提供Python标准内建容器dict、list、set、tuple的替代选择。
Counter:字典的子类,提供了可哈希对象的计数功能。
defaultdict:字典的子类,提供了一个工厂函数,为字典查询提供了默认值。
OrderedDict:字典的子类,保留了他们被添加的顺序。
namedtuple:创建命名元组子类的工厂函数。
deque:类似列表容器,实现了在两端快速添加(append)和弹出(pop)。
ChainMap:类似字典的容器类,将多个映射集合到一个视图里面。
Counter
Counter是一个dict子类,主要是用来对你访问的对象的频率进行计数。
>>>importcollections
>>>#统计字符出现的次数
...collections.Counter('helloworld')
Counter({'l':3,'o':2,'h':1,'e':1,'':1,'w':1,'r':1,'d':1})
>>>#统计单词个数
...collections.Counter('helloworldhellolucy'.split())
Counter({'hello':2,'world':1,'lucy':1})
常用方法:
elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。
most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数
subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数
update([iterable-or-mapping]):从迭代对象计数元素或者从另一个映射对象(或计数器)添加。
>>>c=collections.Counter('helloworldhellolucy'.split())
>>>c
Counter({'hello':2,'world':1,'lucy':1})
>>>#获取指定对象的访问次数,也可以使用get方法
...c['hello']
2
>>>#查看元素
...list(c.elements())
['hello','hello','world','lucy']
>>>c1=collections.Counter('helloworld'.split())
>>>c2=collections.Counter('hellolucy'.split())
>>>c1
Counter({'hello':1,'world':1})
>>>c2
Counter({'hello':1,'lucy':1})
>>>#追加对象,+或者c1.update(c2)
...c1+c2
Counter({'hello':2,'world':1,'lucy':1})
>>>#减少对象,-或者c1.subtract(c2)
...c1-c2
Counter({'world':1})
>>>#清除
...c.clear()
>>>c
Counter()
defaultdict
返回一个新的类似字典的对象。defaultdict是内置dict类的子类。
classcollections.defaultdict([default_factory[,...]])
>>>d=collections.defaultdict()
>>>d
defaultdict(None,{})
>>>e=collections.defaultdict(str)
>>>e
defaultdict(,{})
例子
defaultdict的一个典型用法是使用其中一种内置类型(如str、int、list或dict等)作为默认工厂,这些内置类型在没有参数调用时返回空类型。
>>>e=collections.defaultdict(str) >>>e defaultdict(,{}) >>>e['hello'] '' >>>e defaultdict( ,{'hello':''}) >>>#普通字典调用不存在的键时,报错 ...e1={} >>>e1['hello'] Traceback(mostrecentcalllast): File" ",line1,in KeyError:'hello' 使用int作为default_factory >>>fruit=collections.defaultdict(int) >>>fruit['apple']=2 >>>fruit defaultdict( ,{'apple':2}) >>>fruit['banana']#没有对象时,返回0 0 >>>fruit defaultdict( ,{'apple':2,'banana':0})
使用list作为default_factory
>>>s=[('yellow',1),('blue',2),('yellow',3),('blue',4),('red',1)]
>>>d=collections.defaultdict(list)
>>>fork,vins:
...d[k].append(v)
...
>>>d
defaultdict(,{'yellow':[1,3],'blue':[2,4],'red':[1]})
>>>d.items()
dict_items([('yellow',[1,3]),('blue',[2,4]),('red',[1])])
>>>sorted(d.items())
[('blue',[2,4]),('red',[1]),('yellow',[1,3])]
使用dict作为default_factory
```python
>>>nums=collections.defaultdict(dict)
>>>nums[1]={'one':1}
>>>nums
defaultdict(,{1:{'one':1}})
>>>nums[2]
{}
>>>nums
defaultdict(,{1:{'one':1},2:{}})
使用set作为default_factory
```python
>>>types=collections.defaultdict(set)
>>>types['手机'].add('华为')
>>>types['手机'].add('小米')
>>>types['显示器'].add('AOC')
>>>types
defaultdict(,{'手机':{'华为','小米'},'显示器':{'AOC'}})
##OrderedDict
Python字典中的键的顺序是任意的,它们不受添加的顺序的控制。
collections.OrderedDict类提供了保留他们添加顺序的字典对象。
```python
>>>o=collections.OrderedDict()
>>>o['k1']='v1'
>>>o['k3']='v3'
>>>o['k2']='v2'
>>>o
OrderedDict([('k1','v1'),('k3','v3'),('k2','v2')])
如果在已经存在的key上添加新的值,将会保留原来的key的位置,然后覆盖value值。
```python
>>>o['k1']=666
>>>o
OrderedDict([('k1',666),('k3','v3'),('k2','v2')])
>>>dict(o)
{'k1':666,'k3':'v3','k2':'v2'}
##namedtuple
三种定义命名元组的方法:第一个参数是命名元组的构造器(如下的:Person1,Person2,Person3)
```python
>>>P1=collections.namedtuple('Person1',['name','age','height'])
>>>P2=collections.namedtuple('Person2','name,age,height')
>>>P3=collections.namedtuple('Person3','nameageheight')
实例化命名元组
```python
>>>lucy=P1('lucy',23,180)
>>>lucy
Person1(name='lucy',age=23,height=180)
>>>jack=P2('jack',20,190)
>>>jack
Person2(name='jack',age=20,height=190)
>>>lucy.name#直接通过实例名.属性来调用
'lucy'
>>>lucy.age
23
deque
collections.deque返回一个新的双向队列对象,从左到右初始化(用方法append()),从iterable(迭代对象)数据创建。如果iterable没有指定,新队列为空。
collections.deque队列支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)。
虽然list对象也支持类似操作,但是这里优化了定长操作(pop(0)、insert(0,v))的开销。
如果maxlen没有指定或者是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超出长度maxlen的话,就抛出一个IndexError。
pop():移除最右侧的元素。
popleft():移除最左侧的元素。
remove(value):移去找到的第一个value。没有抛出ValueError。
reverse():将deque逆序排列。返回None。
maxlen:队列的最大长度,没有限定则为None。
>>>d=collections.deque(maxlen=10)
>>>d
deque([],maxlen=10)
>>>d.extend('python')
>>>[i.upper()foriind]
['P','Y','T','H','O','N']
>>>d.append('e')
>>>d.appendleft('f')
>>>d.appendleft('g')
>>>d.appendleft('h')
>>>d
deque(['h','g','f','p','y','t','h','o','n','e'],maxlen=10)
>>>d.appendleft('i')
>>>d
deque(['i','h','g','f','p','y','t','h','o','n'],maxlen=10)
>>>d.append('m')
>>>d
deque(['h','g','f','p','y','t','h','o','n','m'],maxlen=10)
##ChainMap
问题背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap。
可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。简单使用:
```python
>>>d1={'apple':1,'banana':2}
>>>d2={'orange':2,'apple':3,'pike':1}
>>>combined1=collections.ChainMap(d1,d2)
>>>combined2=collections.ChainMap(d2,d1)
>>>combined1
ChainMap({'apple':1,'banana':2},{'orange':2,'apple':3,'pike':1})
>>>combined2
ChainMap({'orange':2,'apple':3,'pike':1},{'apple':1,'banana':2})
>>>fork,vincombined1.items():
...print(k,v)
...
orange2
apple1
pike1
banana2
>>>fork,vincombined2.items():
...print(k,v)
...
apple3
banana2
orange2
pike1
有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改,如果第一个字典不存在该键,会添加。
>>>d1={'apple':1,'banana':2} >>>d2={'orange':2,'apple':3,'pike':1} >>>c=collections.ChainMap(d1,d2) >>>c ChainMap({'apple':1,'banana':2},{'orange':2,'apple':3,'pike':1}) >>>c['apple'] 1 >>>c['apple']=2 >>>c ChainMap({'apple':2,'banana':2},{'orange':2,'apple':3,'pike':1}) >>>c['pike'] 1 >>>c['pike']=3 >>>c ChainMap({'apple':2,'banana':2,'pike':3},{'orange':2,'apple':3,'pike':1}) 从原理上面讲,ChainMap实际上是把放入的字典存储在一个队列中,当进行字典的增加删除等操作只会在第一个字典上进行,当进行查找的时候会依次查找,new_child()方法实质上是在列表的第一个元素前放入一个字典,默认是{},而parents是去掉了列表开头的元素。 ```python >>>a=collections.ChainMap() >>>a['x']=1 >>>a ChainMap({'x':1}) >>>b=a.new_child() >>>b ChainMap({},{'x':1}) >>>b['x']=2 >>>b ChainMap({'x':2},{'x':1}) >>>b['y']=3 >>>b ChainMap({'x':2,'y':3},{'x':1}) >>>a ChainMap({'x':1}) >>>c=a.new_child() >>>c ChainMap({},{'x':1}) >>>c['x']=1 >>>c['y']=1 >>>c ChainMap({'x':1,'y':1},{'x':1}) >>>d=c.parents >>>d ChainMap({'x':1}) >>>disa False >>>d==a True >>>a={'x':1,'z':3} >>>b={'y':2,'z':4} >>>c=collections.ChainMap(a,b) >>>c ChainMap({'x':1,'z':3},{'y':2,'z':4}) >>>c.maps [{'x':1,'z':3},{'y':2,'z':4}] >>>c.parents ChainMap({'y':2,'z':4}) >>>c.parents.maps [{'y':2,'z':4}] >>>c.parents.parents ChainMap({}) >>>c.parents.parents.parents ChainMap({})
到此这篇关于Python的collections模块真的很好用的文章就介绍到这了,更多相关Python的collections模块内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。