使用生成器时访问连续项
问题内容:
可以说我有一个元组生成器,其模拟如下:
g = (x for x in (1,2,3,97,98,99))
对于这个特定的生成器,我希望编写一个函数来输出以下内容:
(1,2,3)
(2,3,97)
(3,97,98)
(97,98,99)
(98,99)
(99)
因此,我要遍历三个连续的项目并打印它们,除非我快要结束了。
我函数的第一行应该是:
t = tuple(g)
换句话说,最好直接在元组上工作,还是与生成器一起工作可能会有所好处。如果可以使用两种方法都可以解决此问题,请说明两种方法的优缺点。另外,如果使用生成器方法可能是明智的选择,那么这种解决方案会如何?
这是我目前正在做的事情:
def f(data, l):
t = tuple(data)
for j in range(len(t)):
print(t[j:j+l])
data = (x for x in (1,2,3,4,5))
f(data,3)
更新 :
请注意,我已经更新了函数,以使用第二个参数来指定窗口的长度。
问题答案:
如果一次可能需要三个以上的元素,并且不想将整个生成器加载到内存中,建议使用标准库中的deque
fromcollections
模块存储当前项集。一个deque
(发音为“
deck”,意思是“双端队列”)可以从两端有效地推送和弹出值。
from collections import deque
from itertools import islice
def get_tuples(gen, n):
q = deque(islice(gen, n)) # pre-load the queue with `n` values
while q: # run until the queue is empty
yield tuple(q) # yield a tuple copied from the current queue
q.popleft() # remove the oldest value from the queue
try:
q.append(next(gen)) # try to add a new value from the generator
except StopIteration:
pass # but we don't care if there are none left