deque对象-collections- 容器数据类型(29)Python语言(必读进阶学习教程)(参考资料)
- class
collections.
deque
([iterable[, maxlen]]) - 返回一个新的 deque 对象,该对象使用iterable中的数据从左到右初始化(使用
append()
)。如果未指定iterable ,则新双端队列为空。双端队列是栈和队列的概括(名称发音为“deck”,是“双端队列”的缩写)。双端队列支持从双端队列的任一侧进行线程安全、内存高效的追加和弹出操作,在任一方向上的 O(1) 性能大致相同。
尽管列表对象支持类似的操作,但它们针对快速固定长度操作进行了优化,并且会为 pop(0) 和 insert(0, v) 操作带来 O(n) 内存移动成本,这会改变基础数据表示的大小和位置 .
如果maxlen未指定或为
None
,则双端队列可能会增长到任意长度。否则,双端队列被限制为指定的最大长度。一旦有界长度的双端队列已满,当添加新项目时,相应数量的项目将从另一端丢弃。有界长度双端队列提供类似于tail
Unix 中的过滤器的功能。它们也可用于跟踪交易和其他仅关注最近活动的数据池。Deque 对象支持以下方法:
append
( x )- 将x添加到双端队列的右侧。
appendleft
( x )- 将x添加到双端队列的左侧。
clear
()- 从 deque 中删除所有元素,使其长度为 0。
copy
()- 创建双端队列的浅表副本。
3.5 版中的新功能。
count
( x )- 计算等于x的双端队列元素的数量。
3.2 版中的新功能。
iterableextend(
)
- 通过附加可迭代参数中的元素来扩展双端队列的右侧。
iterableextendleft(
)
- 通过附加来自iterable的元素来扩展双端队列的左侧。请注意,一系列左追加会导致可迭代参数中元素顺序的颠倒。
xindex(
start[,
stop[,
]])
- 返回 x 在双端队列中的位置(在索引开始时或之后以及索引停止之前)。 返回第一个匹配项,如果未找到则引发 ValueError。
3.5 版中的新功能。
iinsert(
x,
)
- 将 x 插入双端队列中的位置 i。
如果插入会导致有界双端队列增长超过 maxlen,则会引发 IndexError。
3.5 版中的新功能。
pop
()- 从双端队列的右侧移除并返回一个元素。如果不存在任何元素,则引发
IndexError
.
popleft
()- 从双端队列的左侧移除并返回一个元素。如果不存在任何元素,则引发
IndexError
.
valueremove(
)
- 删除第一次出现的值。如果未找到,则引发
ValueError
.
reverse
()- 就地反转双端队列的元素,然后返回
None
。3.2 版中的新功能。
rotate
( n=1 )- 将双端队列向右旋转n 个步骤。如果n为负数,则向左旋转。
当双端队列不为空时,向右
d.appendleft(d.pop())
旋转一级相当于 ,向左旋转一级相当于d.append(d.popleft())
。
Deque 对象还提供一个只读属性:
maxlen
- 双端队列的最大大小,如果无界则为 None。
3.1 版中的新功能。
除了上述之外,双端队列还支持迭代、pickling、len(d)
、 reversed(d)
、copy.copy(d)
、copy.deepcopy(d)
、使用运算符的成员资格测试in
以及下标引用,例如d[-1]
. 索引访问在两端是 O(1),但在中间减慢到 O(n)。对于快速随机访问,请改用列表。
从版本 3.5 开始,双端队列支持__add__()
、__mul__()
和__imul__()
。
例子:
>>> from collections import deque >>> d = deque('ghi') # make a new deque with three items >>> for elem in d: # iterate over the deque's elements ... print(elem.upper()) G H I >>> d.append('j') # add a new entry to the right side >>> d.appendleft('f') # add a new entry to the left side >>> d # show the representation of the deque deque(['f', 'g', 'h', 'i', 'j']) >>> d.pop() # return and remove the rightmost item 'j' >>> d.popleft() # return and remove the leftmost item 'f' >>> list(d) # list the contents of the deque ['g', 'h', 'i'] >>> d[0] # peek at leftmost item 'g' >>> d[-1] # peek at rightmost item 'i' >>> list(reversed(d)) # list the contents of a deque in reverse ['i', 'h', 'g'] >>> 'h' in d # search the deque True >>> d.extend('jkl') # add multiple elements at once >>> d deque(['g', 'h', 'i', 'j', 'k', 'l']) >>> d.rotate(1) # right rotation >>> d deque(['l', 'g', 'h', 'i', 'j', 'k']) >>> d.rotate(-1) # left rotation >>> d deque(['g', 'h', 'i', 'j', 'k', 'l']) >>> deque(reversed(d)) # make a new deque in reverse order deque(['l', 'k', 'j', 'i', 'h', 'g']) >>> d.clear() # empty the deque >>> d.pop() # cannot pop from an empty deque Traceback (most recent call last): File "<pyshell#6>", line 1, in -toplevel- d.pop() IndexError: pop from an empty deque >>> d.extendleft('abc') # extendleft() reverses the input order >>> d deque(['c', 'b', 'a'])
deque用法
本节展示了使用deque的各种方法。
有界长度deque提供类似于 Unix 中的尾部过滤器的功能:
def tail(filename, n=10): 'Return the last n lines of a file' with open(filename) as f: return deque(f, n)
使用deque的另一种方法是通过向右追加和向左弹出来维护最近添加的元素的序列:
def moving_average(iterable, n=3): # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 # http://en.wikipedia.org/wiki/Moving_average it = iter(iterable) d = deque(itertools.islice(it, n-1)) d.appendleft(0) s = sum(d) for elem in it: s += elem - d.popleft() d.append(elem) yield s / n
可以使用存储在deque
. 值从位置零的活动迭代器中产生。如果那个迭代器用完了,它可以被删除popleft()
;否则,可以使用以下rotate()
方法循环回到末尾:
def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" iterators = deque(map(iter, iterables)) while iterators: try: while True: yield next(iterators[0]) iterators.rotate(-1) except StopIteration: # Remove an exhausted iterator. iterators.popleft()
rotate() 方法提供了一种实现双端队列切片和删除的方法。 例如,del d[n] 的纯 Python 实现依赖于 rotate() 方法来定位要弹出的元素:
def delete_nth(d, n): d.rotate(-n) d.popleft() d.rotate(n)
要实现deque
切片,请使用类似的方法应用 rotate() 将目标元素带到deque
的左侧。 使用 popleft() 删除旧条目,使用 extend() 添加新条目,然后反转旋转。 通过对该方法的微小改动,可以轻松实现 Forth 风格的堆栈操作,例如 dup、drop、swap、over、pick、rot 和 roll。