我正在尝试制作一个可以在列表中返回多个连续项目的生成器,这些项目会移动"只有一个指数。与DSP中的移动平均滤波器类似的东西。例如,如果我有列表:
l = [1,2,3,4,5,6,7,8,9]
我希望这个输出:
[(1,2,3),(2,3,4),(3,4,5),(4,5,6),(5,6,7),(6,7,8),(7,8,9)]
我已经制作了代码,但它不适用于过滤器和生成器等。如果我需要提供大量的单词列表,我担心它也会因内存而中断。
功能gen
:
def gen(enumobj, n):
for idx,val in enumerate(enumobj):
try:
yield tuple(enumobj[i] for i in range(idx, idx + n))
except:
break
和示例代码:
words = ['aaa','bb','c','dddddd','eeee','ff','g','h','iiiii','jjj','kk','lll','m','m','ooo']
w = filter(lambda x: len(x) > 1, words)
# It's working with list
print('\nList:')
g = gen(words, 4)
for i in g: print(i)
# It's not working with filetrs / generators etc.
print('\nFilter:')
g = gen(w, 4)
for i in g: print(i)
列表中没有任何内容。代码应该中断,因为无法索引过滤器对象。当然,其中一个答案是强制列表:list(w)
。但是,我正在寻找更好的功能代码。如何更改它以便函数可以接受过滤器等。我担心列表中的大量数据的内存。
由于
答案 0 :(得分:1)
使用迭代器,您需要跟踪已经读取的值。一个n
大小的列表可以解决问题。将下一个值附加到列表中,并在每次收益后丢弃顶部项目。
import itertools
def gen(enumobj, n):
# we need an iterator for the `next` call below. this creates
# an iterator from an iterable such as a list, but leaves
# iterators alone.
enumobj = iter(enumobj)
# cache the first n objects (fewer if iterator is exhausted)
cache = list(itertools.islice(enumobj, n))
# while we still have something in the cache...
while cache:
yield cache
# drop stale item
cache.pop(0)
# try to get one new item, stopping when iterator is done
try:
cache.append(next(enumobj))
except StopIteration:
# pass to emit progressively smaller units
#pass
# break to stop when fewer than `n` items remain
break
words = ['aaa','bb','c','dddddd','eeee','ff','g','h','iiiii','jjj','kk','lll','m','m','ooo']
w = filter(lambda x: len(x) > 1, words)
# It's working with list
print('\nList:')
g = gen(words, 4)
for i in g: print(i)
# now it works with iterators
print('\nFilter:')
g = gen(w, 4)
for i in g: print(i)