python高级容器collections --deque

collections模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。

包含namedtupledequeChainMapCounterOrderedDictdefaultdict等。

本章讲解deque,基于python3.10。

简介

collections.deque([iterable[, maxlen]])

参数:
iterable:从 iterable (迭代对象) 数据创建对象。如果 iterable 没有指定,新队列为空;
maxlen:可选参数,如果没有指定或者是 None ,deques 可以增长到任意长度。否则,deque就限定到指定最大长度。

Deque队列是由栈或者queue队列生成的(发音是 “deck”,”double-ended queue”的简称)。Deque 支持线程安全,内存高效添加(append)和弹出(pop),从两端都可以,两个方向的大概开销都是 O(1) 复杂度。

虽然 list 对象也支持类似操作,不过这里优化了定长操作和 pop(0) 和 insert(0, v) 的开销。它们引起 O(n) 内存移动的操作,改变底层数据表达的大小和位置。

一旦限定长度的deque满了,当新项加入时,同样数量的项就从另一端弹出。限定长度deque提供类似Unix filter tail 的功能。它们同样可以用与追踪最近的交换和其他数据池活动。

主要方法

  1. append(x):添加 x 到右端;
  2. appendleft(x):添加 x 到左端;
  3. clear():移除所有元素,使其长度为0;
  4. copy():创建一份浅拷贝;
  5. count(x):计算 deque 中元素等于 x 的个数;
  6. extend(iterable):扩展deque的右侧,通过添加iterable参数中的元素;
  7. extendleft(iterable):扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加;
  8. index(x[, start[, stop]]):返回 x 在 deque 中的位置(在索引 start 之后,索引 stop 之前)。 返回第一个匹配项,如果未找到则引发 ValueError;
  9. insert(i, x):在位置 i 插入 x ,如果插入会导致一个限长 deque 超出长度 maxlen 的话,就引发一个 IndexError;
  10. pop():移去并且返回一个元素,deque 最右侧的那一个。 如果没有元素的话,就引发一个 IndexError;
  11. popleft():移去并且返回一个元素,deque 最左侧的那一个。 如果没有元素的话,就引发 IndexError;
  12. remove(value):移除找到的第一个 value。 如果没有的话就引发 ValueError;
  13. reverse():将deque逆序排列。返回 None ;
  14. rotate(n=1):向右循环移动 n 步。 如果 n 是负数,就向左循环。如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()) , 向左循环一步就等价于d.append(d.popleft()) ;
  15. maxlen:只读属性,Deque的最大尺寸,如果没有限定的话就是 None ;

除了以上操作,deque 还支持迭代、封存、len(d)、reversed(d)、copy.copy(d)、copy.deepcopy(d)、成员检测运算符 in 以及下标引用例如通过 d[0] 访问首个元素等。 索引访问在两端的复杂度均为 O(1) 但在中间则会低至 O(n)。 如需快速随机访问,请改用列表。

Deque从版本3.5开始支持 __add__(), __mul__(), 和 __imul__()

from collections import deque


d = deque('ghi')

# 遍历元素
for elem in d:
    print(elem.upper())

d.append('j')
d.appendleft('f')
print(d)  # deque(['f', 'g', 'h', 'i', 'j'])

print(d.pop())  # j
print(d.popleft())  # f

# 转为列表
print(list(d))  # ['g', 'h', 'i']

# 索引
print(d[0])  # g
print(d[-1])  # i

print(list(reversed(d)))  # ['i', 'h', 'g']

print('h' in d)  # True

d.extend('jkl')
print(d)  # deque(['g', 'h', 'i', 'j', 'k', 'l'])

d.rotate(1)
print(d)  # deque(['l', 'g', 'h', 'i', 'j', 'k'])

print(deque(reversed(d)))  # deque(['k', 'j', 'i', 'h', 'g', 'l'])

d.clear()

d.pop()  # IndexError: pop from an empty deque

用法

一个 轮询调度器 可以通过在 deque 中放入迭代器来实现。值从当前迭代器的位置0被取出并暂存(yield)。 如果这个迭代器消耗完毕,就用 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()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值