deque的英文意思是Double-Ended Queue,从字面的意思来看,他就是一个双向队列。我们使用list存储数据的时候,按索引访问元素很快,因为list是线性存储,数据量很大的时候在列表头插入和删除元素的效率就会很慢。为什么list效率低呢?
因为list有append()和insert(indexvalue)两个添加方法,append()方法只能在在列表的尾部追加元素,而insert(index)虽然能在指定的位置去添加元素,但是他需要去遍历list才行所以时间复杂度为o(N)。
而list中的删除有del names[index]pop()或者pop(index)remove(value)可以看出list删除除了pop()[删除列表末尾的元素]之外,剩下的都需要去遍历list列表,所以时间复杂度是o(N)。
deque是为了在两端高效实现插入和删除操作的双向列表,适合用于队列和栈:deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部或者尾部添加或删除元素。
双端队列支持线程安全,在双端队列的任何一端执行添加和删除操作,它们的内存效率几乎相同(时间复杂度为O(1))。
虽然list也支持类似的操作,但是它对定长列表的操作表现很不错,而当遇到pop(0)和insert(0 v)这样既改变了列表的长度又改变其元素位置的操作时,其时间复杂度就变为O(n)了。
在双端队列中最好不使用切片(如果使用deque进行切片的话会抛出异常)和索引(和列表一样的使用,虽然效果上是一样的,但是可能效率上还是列表的索引效率更高一些),你可以用popleft和appendleft方法,双端队列对这些操作做了优化。在两端的索引访问时间复杂度为O(1),但是访问中间元素的时间复杂度为O(n),速度较慢,对于快速随机的访问,还是用列表代替。
列表用于随机访问和定长数据的操作,包括切片,而双端队列适用于在两端压入或弹出元素,索引的效率可能低于列表,同时也不支持切片。
rotate(把右边元素放到左边,默认为1)
还有一个值得关注的地方,初始化deque的时候可以给他传一个参数maxlen,如果deque中的元素超过maxlen的值,那么就会从deque中的一边去删除元素,也就是deque始终保持maxlen最大长度的元素,如果超过了就会自动把以前的元素弹出(删除)。当然这些追加都是没有问题的。
当时如果我使用insert(indexvalue)就会抛出异常。当然这种情况出现在我队列中的元素==maxlen的情况下使用insert才会抛出异常。如果元素!=maxlen的时候insert没有问题。我觉得可能在指定位置插入的话,他不知道去删除那一端的元素。