我在StackOverflow中遇到了一些代码,提出了两个关于deque
工作方式的问题。我没有足够的声誉来问“原地”,因此这个问题:
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))
代码计算序列上给定大小的滑动窗口。 我不明白的步骤是:
q = deque(islice(it, size), maxlen=size)
maxlen
在这有什么用? islice
总是不会输出最长size
的可迭代?
第二名:
yield iter(q) # iter() to avoid accidental outside modifications
为什么我们需要转换为可迭代以避免“意外的外部修改”?
答案 0 :(得分:1)
要回答问题的第一部分,设置maxlen会在添加项目时使deque不超过该大小 - 旧项目将被丢弃。
答案 1 :(得分:1)
要回答问题的第二部分,Python中的所有内容都通过引用传递。因此,在上面生成器的情况下, q
是对函数的原始deque持有的引用,因此任何可以修改deque的方法都会破坏生成的原始算法。当你用q
围绕iter()
时,你实际产生的是一个迭代器。您可以从迭代器(读取)中获取元素,但不能自行更改元素或修改它们的顺序(不允许写入)。因此,保护内部容器保持免受意外损坏是一种很好的做法。