python 双端队列的理解

python deque understanding

我在 Whosebug 中发现了一些代码,这些代码提出了两个关于 deque 工作方式的问题。我没有足够的声誉来问 "in situ",因此这个问题:

from collections import deque
from itertools import islice

def sliding_window(iterable, size=2, step=1, fillvalue=None):
    if size < 0 or step < 1:
        raise ValueError
    it = iter(iterable)
    q = deque(islice(it, size), maxlen=size)
    if not q:
        return  # empty iterable or size == 0
    q.extend(fillvalue for _ in range(size - len(q)))  # pad to size
    while True:
        yield iter(q)  # iter() to avoid accidental outside modifications
        q.append(next(it))
        q.extend(next(it, fillvalue) for _ in range(step - 1))

代码计算给定大小在序列上的滑动 window。 不懂的步骤先:

q = deque(islice(it, size), maxlen=size)

这里maxlen有什么用?是不是 islice 总是要输出一个最大长度为 size 的迭代器?

第二个:

yield iter(q)  # iter() to avoid accidental outside modifications

为什么我们需要转换为可迭代以避免"accidental outside modifications"?

要回答问题的第一部分,设置 maxlen 将使双端队列在添加项目时不超过该大小 - 旧项目将被丢弃。

为了回答问题的第二部分,Python 中的所有内容均通过引用传递。因此,在上面的情况下 generator q 是对函数持有的原始双端队列的引用,因此任何可能修改双端队列的方法都会破坏生成的原始算法。当你用 iter() 包围 q 时,你有效地产生了一个迭代器。您可以从迭代器中获取元素(读取),但不能更改元素本身或修改它们的顺序(不允许写入)。因此,防止意外损坏发电机内部的容器是一个很好的做法。