当前位置:Gxlcms > Python > 详解Python的collections模块中的deque双端队列结构

详解Python的collections模块中的deque双端队列结构

时间:2021-07-01 10:21:17 帮助过:39人阅读

deque 是 double-ended queue的缩写,类似于 list,不过提供了在两端插入和删除的操作。

  • appendleft 在列表左侧插入
  • popleft 弹出列表左侧的值
  • extendleft 在左侧扩展

例如:

  1. queue = deque()
  2. # append values to wait for processing
  3. queue.appendleft("first")
  4. queue.appendleft("second")
  5. queue.appendleft("third")
  6. # pop values when ready
  7. process(queue.pop()) # would process "first"
  8. # add values while processing
  9. queue.appendleft("fourth")
  10. # what does the queue look like now?
  11. queue # deque(['fourth', 'third', 'second'])

作为一个双端队列,deque还提供了一些其他的好用方法,比如 rotate 等,下面我们一起来看一下:

填充
deque可以从任意一端填充,在python实现称为“左端”和“右端”。

  1. import collections
  2. d1 = collections.deque()
  3. d1.extend('abcdefg')
  4. print 'extend:', d1
  5. d1.append('h')
  6. print 'append:', d1
  7. d2 = collections.deque()
  8. d2.extendleft(xrange(6))
  9. print 'extendleft', d2
  10. d2.appendleft(6)
  11. print 'appendleft', d2

extendleft()迭代处理其输入,对每个元素完成与appendleft()相同的处理。

  1. extend: deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
  2. append: deque(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
  3. extendleft deque([5, 4, 3, 2, 1, 0])
  4. appendleft deque([6, 5, 4, 3, 2, 1, 0])

利用
可以从两端利用deque元素,取决于应用的算法。

  1. import collections
  2. print "From the right:"
  3. d = collections.deque('abcdefg')
  4. while True:
  5. try:
  6. print d.pop(),
  7. except IndexError:
  8. break
  9. print
  10. print "\nFrom the left:"
  11. d = collections.deque(xrange(6))
  12. while True:
  13. try:
  14. print d.popleft(),
  15. except IndexError:
  16. break
  17. print

使用pop()可以从deque右端删除一个元素,使用popleft()可以从deque左端删除一个元素。

  1. From the right:
  2. g f e d c b a
  3. From the left:
  4. 0 1 2 3 4 5

由于双端队列是线程安全的,可以在不同的线程中同时从两端利用队列的内容。

  1. import collections
  2. import threading
  3. import time
  4. candle = collections.deque(xrange(5))
  5. def burn(direction, nextSource):
  6. while True:
  7. try:
  8. next = nextSource()
  9. except IndexError:
  10. break
  11. else:
  12. print '%8s: %s' % (direction, next)
  13. time.sleep(0.1)
  14. print '%8s done' % direction
  15. return
  16. left = threading.Thread(target=burn, args=('Left', candle.popleft))
  17. right = threading.Thread(target=burn, args=('Right', candle.pop))
  18. left.start()
  19. right.start()
  20. left.join()
  21. right.join()

线程交替处理两端,删除元素,知道这个deque为空。

  1. Left: 0 Right: 4
  2. Right: 3 Left: 1
  3. Right: 2 Left done
  4. Right done

旋转
deque另外一个作用可以按照任意一个方向旋转,而跳过一些元素。

  1. import collections
  2. d = collections.deque(xrange(10))
  3. print 'Normal:', d
  4. d= collections.deque(xrange(10))
  5. d.rotate(2)
  6. print 'Right roration:', d
  7. d = collections.deque(xrange(10))
  8. d.rotate(-2)
  9. print 'Left roration:', d

结果:

  1. Normal: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  2. Right roration: deque([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
  3. Left roration: deque([2, 3, 4, 5, 6, 7, 8, 9, 0, 1])

再举个例子:

  1. # -*- coding: utf-8 -*-
  2. """
  3. 下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
  4. 的加载动画
  5. """
  6. import sys
  7. import time
  8. from collections import deque
  9. fancy_loading = deque('>--------------------')
  10. while True:
  11. print '\r%s' % ''.join(fancy_loading),
  12. fancy_loading.rotate(1)
  13. sys.stdout.flush()
  14. time.sleep(0.08)

输出结果:

  1. # 一个无尽循环的跑马灯
  2. ------------->-------

人气教程排行