python-30 collections相关 模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
namedtuple
带有名称的元组,namedtuple(名称,[属性集])
import collections #1.collections.namedtuple('名称', 属性集),属性集,可以是列表,元组,集合等, # 但是,集合是无序的,p.x,p.y,p.z值每次都是变化的,故不用 # point=collections.namedtuple('point',{'x','y','z'}) point=collections.namedtuple('point',['x','y','z']) p=point(1,2,3) print(p.x,p.y,p.z)
queue:队列
queue模块有三种队列及构造函数:
- Python queue模块的FIFO队列先进先出。 class queue.Queue(maxsize)
- LIFO类似于堆,即先进后出。 class queue.LifoQueue(maxsize)
- 还有一种是优先级队列级别越低越先出来。 class queue.PriorityQueue(maxsize)
queue模块中的常用方法:
- queue.qsize() 返回队列的大小
- queue.empty() 如果队列为空,返回True,反之False
- queue.full() 如果队列满了,返回True,反之False
- queue.full 与 maxsize 大小对应
- queue.get([block[, timeout]])获取队列,timeout等待时间 ,
-
如果无数据可取,默认会阻塞(block=True),阻塞时可以定义超时时间(timeout=2)
- 可以使用block=False设置不阻塞立即报错
-
- queue.get_nowait() 相当queue.get(False)
- queue.put(item) 写入队列,timeout等待时间
- queue.put_nowait(item) 相当queue.put(item, False)
- queue.task_done() 在完成一项工作之后,queue.task_done()函数向任务已经完成的队列发送一个信号
- queue.join() 实际上意味着等到队列为空,再执行别的操作
-
import queue #2.queue队列FIFO q=queue.Queue(3) #定义队列大小,即maxsize=3 def __init__(self, maxsize=0): print("q.maxsize=%d"%(q.maxsize)) q.put(5,) #放入数据 def put(self, item, block=True, timeout=None): q.put(4,False)#可以设置不阻赛,如果队列满了,直接产生raise Full错误 q.put(3) print("队列中现有元素个数:",q.qsize())#q.qsize(),返回队列中现有元素个数,3 print(q.get(),q.get())#取出元素,先进来的2个数被取出,5和4 print("队列中现有元素个数:",q.qsize())#q.qsize(),返回队列中现有元素个数,1 q.put(['a','b','c',7])#列表算1个元素 q.put((4,5)) print('队列中现有元素个数:%s--队列已满吗?'%(q.qsize()))#阻塞后,执行不到这条语句 q.put(2,True,1) #如果队列满了,默认会阻塞(block=True),可以定义阻塞时间(timeout=1),超时后会raise Full错误 #如果block=True,timeout不设置,则会一直处于阻塞中,之后的语句不会执行 print('队列中现有元素个数:%s--队列已满吗?'%(q.qsize()))#阻塞后,执行不到这条语句
-
import queue #2.queue队列FIFO q=queue.Queue(3) #定义队列大小,即maxsize=3 def __init__(self, maxsize=0): print("q.maxsize=%d"%(q.maxsize)) q.put(5,) #放入数据 def put(self, item, block=True, timeout=None): q.put(4,False)#可以设置不阻赛,如果队列满了,直接产生raise Full错误 q.put(3) print("队列中元素个数:",q.qsize())#q.qsize(),返回队列中现有元素个数 q.put(2,True,1) #如果队列满了,默认会阻塞(block=True),可以定义阻塞时间(timeout=1),超时后会raise Full错误 #如果block=True,timeout不设置,则会一直处于阻塞中,之后的语句不会执行 print('队列已满吗?')#阻塞后,执行不到
-
deque:双端对队
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
-
dq=collections.deque(['a','b','c'],2) #创建一个双端对队对象,def __init__(self, iterable=(), maxlen=None) print(dq) #返回deque(['b', 'c'], maxlen=2),进队1-->2-->3顺序,数据长度为2,因为对列先进先出特点,故将'a'溢出 dq.clear()#清空队列内容,但对列长度不被清空,仍为2 print('dq.maxlen=',dq.maxlen)#dq.maxlen= 2,用于定义的时候使用,不能被写入,形如a.maxlen=10会报错 dp=collections.deque([1,2,3]) dp.append('a')#同list的append,在队尾加入一个元素 dp.appendleft('b')#在队首加入一个元素 dp.insert(2,['a','c'])#在索引2前面插入一个元数,即该数索引为2 print(dp)#deque(['b', 1, ['a', 'c'], 2, 3, 'a']) print(dp.count('a'))#计数,返回:1,指定的是一级索下的元素,故列表中'a'不被统计, print(dp[2][0])#返回二级索引中元素'a',即列表中'a' dp.extend('2bc2f')#参数是一个可迭代变量,在对队尾端按照迭代顺序添加 print(dp)#deque(['b', 1, ['a', 'c'], 2, 3, 'a', '2', 'b', 'c', '2', 'f']), print(dp.pop())#弹出对列尾部一个元素:f print(dp.popleft())#弹出对列头部一个元素:b print(dp) res1=dp.remove('2')#同list:用于移除列表中某个值的第一个匹配项. print('res1=%s-->dp=%s'%(res1,dp))#res1=None-->dp=deque([1, ['a', 'c'], 2, 3, 'a', 'b', 'c', '2']) # res1=dp.remove('9')#如果该值不在,则报错 dp.rotate(2)#循环移动,为正全体右移,为负全体左移 print(dp)#deque(['c', '2', 1, ['a', 'c'], 2, 3, 'a', 'b'])
-
OrderedDict:有序字典
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用
OrderedDict
: -
dd={'z':1,'y':5,'x':False,'d':2,'a':3} od=collections.OrderedDict(b=1,a=2,c=3)#产生有序字典,但不那建议这样做 od['z']='4' #这种做法比较好 od['y']='5' od['x']=True print(sorted(dd.items(),key=lambda item:item[0]))#按key排序 print(od)#OrderedDict([('b', 1), ('a', 2), ('c', 3), ('z', '4'), ('y', '5'), ('x', True)])
defaultdict:默认字典 def __init__(self, default_factory=None, **kwargs):
- 其实defaultdict 就是一个字典,只不过python自动的为它的键赋了一个初始值。这也就是说,你不显示的为字典的键赋初值python不会报错,看下实际例子。
- default_factory:参数是一个工厂函数,且是可callable
- 工厂函数:统一了类型和类,即他们看上去有点象函数, 实质上他们是类。当你调用它们时, 实际上是生成了该类型的一个实例, 就象工厂生产货物一样。
- 所有的内建函数都是工厂函数,如 : int(), long(), float(), complex(),bool() ,str(), list(), tuple(),dict(),set(),frozenset()
object(),type(),classmethod(),staticmethod(),super(),property(),file()
- python会抛出一个KeyError 异常,因为字典索引之前必须初始化,可以用defaultdict来解决
-
dd=collections.defaultdict(tuple)#产生个默认值:int(),即0,若是list,则[],tuple是()
print(dd['k'],int(),dd)#则不会报错, 返回:() 0 defaultdict(<class 'tuple'>, {'k': ()})
d2=collections.defaultdict(lambda :5)#参数必需是callable,故可以用函数,直接返回一个值
print(d2['k']) #返回5