详解Python的collections模块中的deque双端队列结构
deque是double-endedqueue的缩写,类似于list,不过提供了在两端插入和删除的操作。
- appendleft在列表左侧插入
- popleft弹出列表左侧的值
- extendleft在左侧扩展
例如:
queue=deque()
#appendvaluestowaitforprocessing
queue.appendleft("first")
queue.appendleft("second")
queue.appendleft("third")
#popvalueswhenready
process(queue.pop())#wouldprocess"first"
#addvalueswhileprocessing
queue.appendleft("fourth")
#whatdoesthequeuelooklikenow?
queue#deque(['fourth','third','second'])
作为一个双端队列,deque还提供了一些其他的好用方法,比如rotate等,下面我们一起来看一下:
填充
deque可以从任意一端填充,在python实现称为“左端”和“右端”。
importcollections
d1=collections.deque()
d1.extend('abcdefg')
print'extend:',d1
d1.append('h')
print'append:',d1
d2=collections.deque()
d2.extendleft(xrange(6))
print'extendleft',d2
d2.appendleft(6)
print'appendleft',d2
extendleft()迭代处理其输入,对每个元素完成与appendleft()相同的处理。
extend:deque(['a','b','c','d','e','f','g']) append:deque(['a','b','c','d','e','f','g','h']) extendleftdeque([5,4,3,2,1,0]) appendleftdeque([6,5,4,3,2,1,0])
利用
可以从两端利用deque元素,取决于应用的算法。
importcollections
print"Fromtheright:"
d=collections.deque('abcdefg')
whileTrue:
try:
printd.pop(),
exceptIndexError:
break
print
print"\nFromtheleft:"
d=collections.deque(xrange(6))
whileTrue:
try:
printd.popleft(),
exceptIndexError:
break
print
使用pop()可以从deque右端删除一个元素,使用popleft()可以从deque左端删除一个元素。
Fromtheright: gfedcba Fromtheleft: 012345
由于双端队列是线程安全的,可以在不同的线程中同时从两端利用队列的内容。
importcollections
importthreading
importtime
candle=collections.deque(xrange(5))
defburn(direction,nextSource):
whileTrue:
try:
next=nextSource()
exceptIndexError:
break
else:
print'%8s:%s'%(direction,next)
time.sleep(0.1)
print'%8sdone'%direction
return
left=threading.Thread(target=burn,args=('Left',candle.popleft))
right=threading.Thread(target=burn,args=('Right',candle.pop))
left.start()
right.start()
left.join()
right.join()
线程交替处理两端,删除元素,知道这个deque为空。
Left:0Right:4 Right:3Left:1 Right:2Leftdone Rightdone
旋转
deque另外一个作用可以按照任意一个方向旋转,而跳过一些元素。
importcollections d=collections.deque(xrange(10)) print'Normal:',d d=collections.deque(xrange(10)) d.rotate(2) print'Rightroration:',d d=collections.deque(xrange(10)) d.rotate(-2) print'Leftroration:',d
结果:
Normal:deque([0,1,2,3,4,5,6,7,8,9]) Rightroration:deque([8,9,0,1,2,3,4,5,6,7]) Leftroration:deque([2,3,4,5,6,7,8,9,0,1])
再举个例子:
#-*-coding:utf-8-*-
"""
下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
的加载动画
"""
importsys
importtime
fromcollectionsimportdeque
fancy_loading=deque('>--------------------')
whileTrue:
print'\r%s'%''.join(fancy_loading),
fancy_loading.rotate(1)
sys.stdout.flush()
time.sleep(0.08)
输出结果:
#一个无尽循环的跑马灯 ------------->-------