如何修改滑动窗口生成器以实现每次步长为2的窗口滑动?
实现步长为2的滑动窗口函数
我明白你遇到的问题了——直接把result[1:]改成result[2:]只会让窗口长度变成2,因为你每次只从迭代器里拿一个元素,根本凑不齐窗口需要的3个元素!咱们来一步步解决这个问题。
问题根源
原代码的逻辑是步长1的滑动:每次从迭代器取1个元素,扔掉窗口最前面的1个元素,把新元素加进去,这样窗口始终保持3个元素。但当你要步长2时,需要扔掉窗口最前面的2个元素,同时得补充2个新元素才能维持窗口长度,而不是只补1个——这就是你之前修改失效的核心原因。
方案1:用索引遍历实现(简单直观)
如果你的输入序列是普通列表(不需要处理超大数据流),直接用索引循环是最容易理解和维护的方式,还能灵活指定步长:
def window(seq, n=3, step=1): # 循环从0开始,每次跳step步,直到窗口末尾不超出序列长度 for i in range(0, len(seq) - n + 1, step): yield seq[i:i+n]
调用这个函数测试你的输入:
My_List= ['adl_01_11', 'adl_01_12', 'adl_01_13', 'adl_01_14', 'adl_02_15', 'adl_02_16', 'adl_02_17', 'adl_02_18', 'adl_02_19', 'adl_02_20', 'adl_02_21', 'adl_02_22'] result = list(window(My_List, n=3, step=2)) print(result)
输出结果(修正了你预期里的笔误,原列表没有adl_01_15这类元素):
[ ['adl_01_11', 'adl_01_12', 'adl_01_13'], ['adl_01_13', 'adl_01_14', 'adl_02_15'], ['adl_02_15', 'adl_02_16', 'adl_02_17'], ['adl_02_17', 'adl_02_18', 'adl_02_19'], ['adl_02_19', 'adl_02_20', 'adl_02_21'] ]
方案2:基于迭代器修改(适合超大序列)
如果你需要处理无法一次性加载到内存的超大数据流,咱们可以修改原有的迭代器逻辑,每次从迭代器里取步长数量的元素来更新窗口:
from itertools import islice def window(seq, n=3, step=1): it = iter(seq) # 初始化第一个窗口 result = list(islice(it, n)) if len(result) == n: yield result # 循环生成后续窗口 while True: # 从迭代器里取step个元素,用来补充窗口 next_elements = list(islice(it, step)) # 如果不够step个元素,说明无法组成完整窗口,停止循环 if len(next_elements) < step: break # 扔掉窗口前step个元素,加上新取的step个元素,维持窗口长度n result = result[step:] + next_elements yield result
这个版本的逻辑和原代码保持一致,用迭代器处理序列,同时支持自定义步长,测试结果和方案1完全相同。
为什么你的修改没用?
你之前只改了result[1:]为result[2:],但原代码的for elem in it每次只取1个元素,导致result = result[2:] + [elem]的长度是1+1=2,根本达不到窗口需要的3个元素,自然得不到正确结果。咱们的修改核心就是保证每次补充的元素数量和扔掉的元素数量一致,维持窗口长度不变。
内容的提问来源于stack exchange,提问作者QQ1821
相关产品推荐
相关产品推荐

